SurfaceFlinger.cpp revision 5df996211d4e263feb862121cfafa7f9c8eeda68
1/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define ATRACE_TAG ATRACE_TAG_GRAPHICS
18
19#include <stdlib.h>
20#include <stdio.h>
21#include <stdint.h>
22#include <unistd.h>
23#include <fcntl.h>
24#include <errno.h>
25#include <math.h>
26#include <limits.h>
27#include <sys/types.h>
28#include <sys/stat.h>
29#include <sys/ioctl.h>
30
31#include <cutils/log.h>
32#include <cutils/properties.h>
33
34#include <binder/IPCThreadState.h>
35#include <binder/IServiceManager.h>
36#include <binder/MemoryHeapBase.h>
37#include <binder/PermissionCache.h>
38
39#include <gui/IDisplayEventConnection.h>
40
41#include <utils/String8.h>
42#include <utils/String16.h>
43#include <utils/StopWatch.h>
44#include <utils/Trace.h>
45
46#include <ui/GraphicBufferAllocator.h>
47#include <ui/PixelFormat.h>
48
49#include <GLES/gl.h>
50
51#include "clz.h"
52#include "DdmConnection.h"
53#include "Client.h"
54#include "EventThread.h"
55#include "GLExtensions.h"
56#include "Layer.h"
57#include "LayerDim.h"
58#include "LayerScreenshot.h"
59#include "SurfaceFlinger.h"
60
61#include "DisplayHardware/DisplayHardware.h"
62#include "DisplayHardware/HWComposer.h"
63
64#include <private/android_filesystem_config.h>
65#include <private/gui/SharedBufferStack.h>
66#include <gui/BitTube.h>
67
68#define EGL_VERSION_HW_ANDROID  0x3143
69
70#define DISPLAY_COUNT       1
71
72namespace android {
73// ---------------------------------------------------------------------------
74
75const String16 sHardwareTest("android.permission.HARDWARE_TEST");
76const String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER");
77const String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER");
78const String16 sDump("android.permission.DUMP");
79
80// ---------------------------------------------------------------------------
81
82SurfaceFlinger::SurfaceFlinger()
83    :   BnSurfaceComposer(), Thread(false),
84        mTransactionFlags(0),
85        mTransationPending(false),
86        mLayersRemoved(false),
87        mBootTime(systemTime()),
88        mVisibleRegionsDirty(false),
89        mHwWorkListDirty(false),
90        mElectronBeamAnimationMode(0),
91        mDebugRegion(0),
92        mDebugDDMS(0),
93        mDebugDisableHWC(0),
94        mDebugDisableTransformHint(0),
95        mDebugInSwapBuffers(0),
96        mLastSwapBufferTime(0),
97        mDebugInTransaction(0),
98        mLastTransactionTime(0),
99        mBootFinished(false),
100        mSecureFrameBuffer(0)
101{
102    init();
103}
104
105void SurfaceFlinger::init()
106{
107    ALOGI("SurfaceFlinger is starting");
108
109    // debugging stuff...
110    char value[PROPERTY_VALUE_MAX];
111
112    property_get("debug.sf.showupdates", value, "0");
113    mDebugRegion = atoi(value);
114
115#ifdef DDMS_DEBUGGING
116    property_get("debug.sf.ddms", value, "0");
117    mDebugDDMS = atoi(value);
118    if (mDebugDDMS) {
119        DdmConnection::start(getServiceName());
120    }
121#else
122#warning "DDMS_DEBUGGING disabled"
123#endif
124
125    ALOGI_IF(mDebugRegion,       "showupdates enabled");
126    ALOGI_IF(mDebugDDMS,         "DDMS debugging enabled");
127}
128
129void SurfaceFlinger::onFirstRef()
130{
131    mEventQueue.init(this);
132
133    run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY);
134
135    // Wait for the main thread to be done with its initialization
136    mReadyToRunBarrier.wait();
137}
138
139
140SurfaceFlinger::~SurfaceFlinger()
141{
142    glDeleteTextures(1, &mWormholeTexName);
143}
144
145void SurfaceFlinger::binderDied(const wp<IBinder>& who)
146{
147    // the window manager died on us. prepare its eulogy.
148
149    // reset screen orientation
150    Vector<ComposerState> state;
151    setTransactionState(state, eOrientationDefault, 0);
152
153    // restart the boot-animation
154    property_set("ctl.start", "bootanim");
155}
156
157sp<IMemoryHeap> SurfaceFlinger::getCblk() const
158{
159    return mServerHeap;
160}
161
162sp<ISurfaceComposerClient> SurfaceFlinger::createConnection()
163{
164    sp<ISurfaceComposerClient> bclient;
165    sp<Client> client(new Client(this));
166    status_t err = client->initCheck();
167    if (err == NO_ERROR) {
168        bclient = client;
169    }
170    return bclient;
171}
172
173sp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc()
174{
175    sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc());
176    return gba;
177}
178
179const GraphicPlane& SurfaceFlinger::graphicPlane(int dpy) const
180{
181    ALOGE_IF(uint32_t(dpy) >= DISPLAY_COUNT, "Invalid DisplayID %d", dpy);
182    const GraphicPlane& plane(mGraphicPlanes[dpy]);
183    return plane;
184}
185
186GraphicPlane& SurfaceFlinger::graphicPlane(int dpy)
187{
188    return const_cast<GraphicPlane&>(
189        const_cast<SurfaceFlinger const *>(this)->graphicPlane(dpy));
190}
191
192void SurfaceFlinger::bootFinished()
193{
194    const nsecs_t now = systemTime();
195    const nsecs_t duration = now - mBootTime;
196    ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
197    mBootFinished = true;
198
199    // wait patiently for the window manager death
200    const String16 name("window");
201    sp<IBinder> window(defaultServiceManager()->getService(name));
202    if (window != 0) {
203        window->linkToDeath(this);
204    }
205
206    // stop boot animation
207    property_set("ctl.stop", "bootanim");
208}
209
210static inline uint16_t pack565(int r, int g, int b) {
211    return (r<<11)|(g<<5)|b;
212}
213
214status_t SurfaceFlinger::readyToRun()
215{
216    ALOGI(   "SurfaceFlinger's main thread ready to run. "
217            "Initializing graphics H/W...");
218
219    // we only support one display currently
220    int dpy = 0;
221
222    {
223        // initialize the main display
224        GraphicPlane& plane(graphicPlane(dpy));
225        DisplayHardware* const hw = new DisplayHardware(this, dpy);
226        plane.setDisplayHardware(hw);
227    }
228
229    // create the shared control-block
230    mServerHeap = new MemoryHeapBase(4096,
231            MemoryHeapBase::READ_ONLY, "SurfaceFlinger read-only heap");
232    ALOGE_IF(mServerHeap==0, "can't create shared memory dealer");
233
234    mServerCblk = static_cast<surface_flinger_cblk_t*>(mServerHeap->getBase());
235    ALOGE_IF(mServerCblk==0, "can't get to shared control block's address");
236
237    new(mServerCblk) surface_flinger_cblk_t;
238
239    // initialize primary screen
240    // (other display should be initialized in the same manner, but
241    // asynchronously, as they could come and go. None of this is supported
242    // yet).
243    const GraphicPlane& plane(graphicPlane(dpy));
244    const DisplayHardware& hw = plane.displayHardware();
245    const uint32_t w = hw.getWidth();
246    const uint32_t h = hw.getHeight();
247    const uint32_t f = hw.getFormat();
248    hw.makeCurrent();
249
250    // initialize the shared control block
251    mServerCblk->connected |= 1<<dpy;
252    display_cblk_t* dcblk = mServerCblk->displays + dpy;
253    memset(dcblk, 0, sizeof(display_cblk_t));
254    dcblk->w            = plane.getWidth();
255    dcblk->h            = plane.getHeight();
256    dcblk->format       = f;
257    dcblk->orientation  = ISurfaceComposer::eOrientationDefault;
258    dcblk->xdpi         = hw.getDpiX();
259    dcblk->ydpi         = hw.getDpiY();
260    dcblk->fps          = hw.getRefreshRate();
261    dcblk->density      = hw.getDensity();
262
263    // Initialize OpenGL|ES
264    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
265    glPixelStorei(GL_PACK_ALIGNMENT, 4);
266    glEnableClientState(GL_VERTEX_ARRAY);
267    glShadeModel(GL_FLAT);
268    glDisable(GL_DITHER);
269    glDisable(GL_CULL_FACE);
270
271    const uint16_t g0 = pack565(0x0F,0x1F,0x0F);
272    const uint16_t g1 = pack565(0x17,0x2f,0x17);
273    const uint16_t wormholeTexData[4] = { g0, g1, g1, g0 };
274    glGenTextures(1, &mWormholeTexName);
275    glBindTexture(GL_TEXTURE_2D, mWormholeTexName);
276    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
277    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
278    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
279    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
280    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0,
281            GL_RGB, GL_UNSIGNED_SHORT_5_6_5, wormholeTexData);
282
283    const uint16_t protTexData[] = { pack565(0x03, 0x03, 0x03) };
284    glGenTextures(1, &mProtectedTexName);
285    glBindTexture(GL_TEXTURE_2D, mProtectedTexName);
286    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
287    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
288    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
289    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
290    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0,
291            GL_RGB, GL_UNSIGNED_SHORT_5_6_5, protTexData);
292
293    glViewport(0, 0, w, h);
294    glMatrixMode(GL_PROJECTION);
295    glLoadIdentity();
296    // put the origin in the left-bottom corner
297    glOrthof(0, w, 0, h, 0, 1); // l=0, r=w ; b=0, t=h
298
299
300    // start the EventThread
301    mEventThread = new EventThread(this);
302    mEventQueue.setEventThread(mEventThread);
303
304    /*
305     *  We're now ready to accept clients...
306     */
307
308    mReadyToRunBarrier.open();
309
310    // start boot animation
311    property_set("ctl.start", "bootanim");
312
313    return NO_ERROR;
314}
315
316// ----------------------------------------------------------------------------
317
318bool SurfaceFlinger::authenticateSurfaceTexture(
319        const sp<ISurfaceTexture>& surfaceTexture) const {
320    Mutex::Autolock _l(mStateLock);
321    sp<IBinder> surfaceTextureBinder(surfaceTexture->asBinder());
322
323    // Check the visible layer list for the ISurface
324    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
325    size_t count = currentLayers.size();
326    for (size_t i=0 ; i<count ; i++) {
327        const sp<LayerBase>& layer(currentLayers[i]);
328        sp<LayerBaseClient> lbc(layer->getLayerBaseClient());
329        if (lbc != NULL) {
330            wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder();
331            if (lbcBinder == surfaceTextureBinder) {
332                return true;
333            }
334        }
335    }
336
337    // Check the layers in the purgatory.  This check is here so that if a
338    // SurfaceTexture gets destroyed before all the clients are done using it,
339    // the error will not be reported as "surface XYZ is not authenticated", but
340    // will instead fail later on when the client tries to use the surface,
341    // which should be reported as "surface XYZ returned an -ENODEV".  The
342    // purgatorized layers are no less authentic than the visible ones, so this
343    // should not cause any harm.
344    size_t purgatorySize =  mLayerPurgatory.size();
345    for (size_t i=0 ; i<purgatorySize ; i++) {
346        const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
347        sp<LayerBaseClient> lbc(layer->getLayerBaseClient());
348        if (lbc != NULL) {
349            wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder();
350            if (lbcBinder == surfaceTextureBinder) {
351                return true;
352            }
353        }
354    }
355
356    return false;
357}
358
359// ----------------------------------------------------------------------------
360
361sp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection() {
362    return mEventThread->createEventConnection();
363}
364
365// ----------------------------------------------------------------------------
366
367void SurfaceFlinger::waitForEvent() {
368    mEventQueue.waitMessage();
369}
370
371void SurfaceFlinger::signalTransaction() {
372    mEventQueue.invalidate();
373}
374
375void SurfaceFlinger::signalLayerUpdate() {
376    mEventQueue.invalidate();
377}
378
379void SurfaceFlinger::signalRefresh() {
380    mEventQueue.refresh();
381}
382
383status_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg,
384        nsecs_t reltime, uint32_t flags) {
385    return mEventQueue.postMessage(msg, reltime);
386}
387
388status_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,
389        nsecs_t reltime, uint32_t flags) {
390    status_t res = mEventQueue.postMessage(msg, reltime);
391    if (res == NO_ERROR) {
392        msg->wait();
393    }
394    return res;
395}
396
397bool SurfaceFlinger::threadLoop()
398{
399    waitForEvent();
400    return true;
401}
402
403void SurfaceFlinger::onMessageReceived(int32_t what)
404{
405    ATRACE_CALL();
406    switch (what) {
407        case MessageQueue::REFRESH: {
408//        case MessageQueue::INVALIDATE: {
409            // if we're in a global transaction, don't do anything.
410            const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
411            uint32_t transactionFlags = peekTransactionFlags(mask);
412            if (CC_UNLIKELY(transactionFlags)) {
413                handleTransaction(transactionFlags);
414            }
415
416            // post surfaces (if needed)
417            handlePageFlip();
418
419//            signalRefresh();
420//
421//        } break;
422//
423//        case MessageQueue::REFRESH: {
424
425            handleRefresh();
426
427            const DisplayHardware& hw(graphicPlane(0).displayHardware());
428
429//            if (mDirtyRegion.isEmpty()) {
430//                return;
431//            }
432
433            if (CC_UNLIKELY(mHwWorkListDirty)) {
434                // build the h/w work list
435                handleWorkList();
436            }
437
438            if (CC_LIKELY(hw.canDraw())) {
439                // repaint the framebuffer (if needed)
440                handleRepaint();
441                // inform the h/w that we're done compositing
442                hw.compositionComplete();
443                postFramebuffer();
444            } else {
445                // pretend we did the post
446                hw.compositionComplete();
447            }
448
449        } break;
450    }
451}
452
453void SurfaceFlinger::postFramebuffer()
454{
455    ATRACE_CALL();
456    // mSwapRegion can be empty here is some cases, for instance if a hidden
457    // or fully transparent window is updating.
458    // in that case, we need to flip anyways to not risk a deadlock with
459    // h/w composer.
460
461    const DisplayHardware& hw(graphicPlane(0).displayHardware());
462    const nsecs_t now = systemTime();
463    mDebugInSwapBuffers = now;
464    hw.flip(mSwapRegion);
465
466    size_t numLayers = mVisibleLayersSortedByZ.size();
467    for (size_t i = 0; i < numLayers; i++) {
468        mVisibleLayersSortedByZ[i]->onLayerDisplayed();
469    }
470
471    mLastSwapBufferTime = systemTime() - now;
472    mDebugInSwapBuffers = 0;
473    mSwapRegion.clear();
474}
475
476void SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
477{
478    ATRACE_CALL();
479
480    Mutex::Autolock _l(mStateLock);
481    const nsecs_t now = systemTime();
482    mDebugInTransaction = now;
483
484    // Here we're guaranteed that some transaction flags are set
485    // so we can call handleTransactionLocked() unconditionally.
486    // We call getTransactionFlags(), which will also clear the flags,
487    // with mStateLock held to guarantee that mCurrentState won't change
488    // until the transaction is committed.
489
490    const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
491    transactionFlags = getTransactionFlags(mask);
492    handleTransactionLocked(transactionFlags);
493
494    mLastTransactionTime = systemTime() - now;
495    mDebugInTransaction = 0;
496    invalidateHwcGeometry();
497    // here the transaction has been committed
498}
499
500void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
501{
502    const LayerVector& currentLayers(mCurrentState.layersSortedByZ);
503    const size_t count = currentLayers.size();
504
505    /*
506     * Traversal of the children
507     * (perform the transaction for each of them if needed)
508     */
509
510    const bool layersNeedTransaction = transactionFlags & eTraversalNeeded;
511    if (layersNeedTransaction) {
512        for (size_t i=0 ; i<count ; i++) {
513            const sp<LayerBase>& layer = currentLayers[i];
514            uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
515            if (!trFlags) continue;
516
517            const uint32_t flags = layer->doTransaction(0);
518            if (flags & Layer::eVisibleRegion)
519                mVisibleRegionsDirty = true;
520        }
521    }
522
523    /*
524     * Perform our own transaction if needed
525     */
526
527    if (transactionFlags & eTransactionNeeded) {
528        if (mCurrentState.orientation != mDrawingState.orientation) {
529            // the orientation has changed, recompute all visible regions
530            // and invalidate everything.
531
532            const int dpy = 0;
533            const int orientation = mCurrentState.orientation;
534            // Currently unused: const uint32_t flags = mCurrentState.orientationFlags;
535            GraphicPlane& plane(graphicPlane(dpy));
536            plane.setOrientation(orientation);
537
538            // update the shared control block
539            const DisplayHardware& hw(plane.displayHardware());
540            volatile display_cblk_t* dcblk = mServerCblk->displays + dpy;
541            dcblk->orientation = orientation;
542            dcblk->w = plane.getWidth();
543            dcblk->h = plane.getHeight();
544
545            mVisibleRegionsDirty = true;
546            mDirtyRegion.set(hw.bounds());
547        }
548
549        if (currentLayers.size() > mDrawingState.layersSortedByZ.size()) {
550            // layers have been added
551            mVisibleRegionsDirty = true;
552        }
553
554        // some layers might have been removed, so
555        // we need to update the regions they're exposing.
556        if (mLayersRemoved) {
557            mLayersRemoved = false;
558            mVisibleRegionsDirty = true;
559            const LayerVector& previousLayers(mDrawingState.layersSortedByZ);
560            const size_t count = previousLayers.size();
561            for (size_t i=0 ; i<count ; i++) {
562                const sp<LayerBase>& layer(previousLayers[i]);
563                if (currentLayers.indexOf( layer ) < 0) {
564                    // this layer is not visible anymore
565                    mDirtyRegionRemovedLayer.orSelf(layer->visibleRegionScreen);
566                }
567            }
568        }
569    }
570
571    commitTransaction();
572}
573
574void SurfaceFlinger::computeVisibleRegions(
575    const LayerVector& currentLayers, Region& dirtyRegion, Region& opaqueRegion)
576{
577    ATRACE_CALL();
578
579    const GraphicPlane& plane(graphicPlane(0));
580    const Transform& planeTransform(plane.transform());
581    const DisplayHardware& hw(plane.displayHardware());
582    const Region screenRegion(hw.bounds());
583
584    Region aboveOpaqueLayers;
585    Region aboveCoveredLayers;
586    Region dirty;
587
588    bool secureFrameBuffer = false;
589
590    size_t i = currentLayers.size();
591    while (i--) {
592        const sp<LayerBase>& layer = currentLayers[i];
593        layer->validateVisibility(planeTransform);
594
595        // start with the whole surface at its current location
596        const Layer::State& s(layer->drawingState());
597
598        /*
599         * opaqueRegion: area of a surface that is fully opaque.
600         */
601        Region opaqueRegion;
602
603        /*
604         * visibleRegion: area of a surface that is visible on screen
605         * and not fully transparent. This is essentially the layer's
606         * footprint minus the opaque regions above it.
607         * Areas covered by a translucent surface are considered visible.
608         */
609        Region visibleRegion;
610
611        /*
612         * coveredRegion: area of a surface that is covered by all
613         * visible regions above it (which includes the translucent areas).
614         */
615        Region coveredRegion;
616
617
618        // handle hidden surfaces by setting the visible region to empty
619        if (CC_LIKELY(!(s.flags & ISurfaceComposer::eLayerHidden) && s.alpha)) {
620            const bool translucent = !layer->isOpaque();
621            const Rect bounds(layer->visibleBounds());
622            visibleRegion.set(bounds);
623            visibleRegion.andSelf(screenRegion);
624            if (!visibleRegion.isEmpty()) {
625                // Remove the transparent area from the visible region
626                if (translucent) {
627                    visibleRegion.subtractSelf(layer->transparentRegionScreen);
628                }
629
630                // compute the opaque region
631                const int32_t layerOrientation = layer->getOrientation();
632                if (s.alpha==255 && !translucent &&
633                        ((layerOrientation & Transform::ROT_INVALID) == false)) {
634                    // the opaque region is the layer's footprint
635                    opaqueRegion = visibleRegion;
636                }
637            }
638        }
639
640        // Clip the covered region to the visible region
641        coveredRegion = aboveCoveredLayers.intersect(visibleRegion);
642
643        // Update aboveCoveredLayers for next (lower) layer
644        aboveCoveredLayers.orSelf(visibleRegion);
645
646        // subtract the opaque region covered by the layers above us
647        visibleRegion.subtractSelf(aboveOpaqueLayers);
648
649        // compute this layer's dirty region
650        if (layer->contentDirty) {
651            // we need to invalidate the whole region
652            dirty = visibleRegion;
653            // as well, as the old visible region
654            dirty.orSelf(layer->visibleRegionScreen);
655            layer->contentDirty = false;
656        } else {
657            /* compute the exposed region:
658             *   the exposed region consists of two components:
659             *   1) what's VISIBLE now and was COVERED before
660             *   2) what's EXPOSED now less what was EXPOSED before
661             *
662             * note that (1) is conservative, we start with the whole
663             * visible region but only keep what used to be covered by
664             * something -- which mean it may have been exposed.
665             *
666             * (2) handles areas that were not covered by anything but got
667             * exposed because of a resize.
668             */
669            const Region newExposed = visibleRegion - coveredRegion;
670            const Region oldVisibleRegion = layer->visibleRegionScreen;
671            const Region oldCoveredRegion = layer->coveredRegionScreen;
672            const Region oldExposed = oldVisibleRegion - oldCoveredRegion;
673            dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed);
674        }
675        dirty.subtractSelf(aboveOpaqueLayers);
676
677        // accumulate to the screen dirty region
678        dirtyRegion.orSelf(dirty);
679
680        // Update aboveOpaqueLayers for next (lower) layer
681        aboveOpaqueLayers.orSelf(opaqueRegion);
682
683        // Store the visible region is screen space
684        layer->setVisibleRegion(visibleRegion);
685        layer->setCoveredRegion(coveredRegion);
686
687        // If a secure layer is partially visible, lock-down the screen!
688        if (layer->isSecure() && !visibleRegion.isEmpty()) {
689            secureFrameBuffer = true;
690        }
691    }
692
693    // invalidate the areas where a layer was removed
694    dirtyRegion.orSelf(mDirtyRegionRemovedLayer);
695    mDirtyRegionRemovedLayer.clear();
696
697    mSecureFrameBuffer = secureFrameBuffer;
698    opaqueRegion = aboveOpaqueLayers;
699}
700
701
702void SurfaceFlinger::commitTransaction()
703{
704    if (!mLayersPendingRemoval.isEmpty()) {
705        // Notify removed layers now that they can't be drawn from
706        for (size_t i = 0; i < mLayersPendingRemoval.size(); i++) {
707            mLayersPendingRemoval[i]->onRemoved();
708        }
709        mLayersPendingRemoval.clear();
710    }
711
712    mDrawingState = mCurrentState;
713    mTransationPending = false;
714    mTransactionCV.broadcast();
715}
716
717void SurfaceFlinger::handlePageFlip()
718{
719    ATRACE_CALL();
720    const DisplayHardware& hw = graphicPlane(0).displayHardware();
721    const Region screenRegion(hw.bounds());
722
723    const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
724    const bool visibleRegions = lockPageFlip(currentLayers);
725
726        if (visibleRegions || mVisibleRegionsDirty) {
727            Region opaqueRegion;
728            computeVisibleRegions(currentLayers, mDirtyRegion, opaqueRegion);
729
730            /*
731             *  rebuild the visible layer list
732             */
733            const size_t count = currentLayers.size();
734            mVisibleLayersSortedByZ.clear();
735            mVisibleLayersSortedByZ.setCapacity(count);
736            for (size_t i=0 ; i<count ; i++) {
737                if (!currentLayers[i]->visibleRegionScreen.isEmpty())
738                    mVisibleLayersSortedByZ.add(currentLayers[i]);
739            }
740
741            mWormholeRegion = screenRegion.subtract(opaqueRegion);
742            mVisibleRegionsDirty = false;
743            invalidateHwcGeometry();
744        }
745
746    unlockPageFlip(currentLayers);
747
748    mDirtyRegion.orSelf(getAndClearInvalidateRegion());
749    mDirtyRegion.andSelf(screenRegion);
750}
751
752void SurfaceFlinger::invalidateHwcGeometry()
753{
754    mHwWorkListDirty = true;
755}
756
757bool SurfaceFlinger::lockPageFlip(const LayerVector& currentLayers)
758{
759    bool recomputeVisibleRegions = false;
760    size_t count = currentLayers.size();
761    sp<LayerBase> const* layers = currentLayers.array();
762    for (size_t i=0 ; i<count ; i++) {
763        const sp<LayerBase>& layer(layers[i]);
764        layer->lockPageFlip(recomputeVisibleRegions);
765    }
766    return recomputeVisibleRegions;
767}
768
769void SurfaceFlinger::unlockPageFlip(const LayerVector& currentLayers)
770{
771    const GraphicPlane& plane(graphicPlane(0));
772    const Transform& planeTransform(plane.transform());
773    const size_t count = currentLayers.size();
774    sp<LayerBase> const* layers = currentLayers.array();
775    for (size_t i=0 ; i<count ; i++) {
776        const sp<LayerBase>& layer(layers[i]);
777        layer->unlockPageFlip(planeTransform, mDirtyRegion);
778    }
779}
780
781void SurfaceFlinger::handleRefresh()
782{
783    bool needInvalidate = false;
784    const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
785    const size_t count = currentLayers.size();
786    for (size_t i=0 ; i<count ; i++) {
787        const sp<LayerBase>& layer(currentLayers[i]);
788        if (layer->onPreComposition()) {
789            needInvalidate = true;
790        }
791    }
792    if (needInvalidate) {
793        signalLayerUpdate();
794    }
795}
796
797
798void SurfaceFlinger::handleWorkList()
799{
800    mHwWorkListDirty = false;
801    HWComposer& hwc(graphicPlane(0).displayHardware().getHwComposer());
802    if (hwc.initCheck() == NO_ERROR) {
803        const Vector< sp<LayerBase> >& currentLayers(mVisibleLayersSortedByZ);
804        const size_t count = currentLayers.size();
805        hwc.createWorkList(count);
806
807        HWComposer::LayerListIterator cur = hwc.begin();
808        const HWComposer::LayerListIterator end = hwc.end();
809        for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
810            currentLayers[i]->setGeometry(*cur);
811            if (mDebugDisableHWC || mDebugRegion) {
812                cur->setSkip(true);
813            }
814        }
815    }
816}
817
818void SurfaceFlinger::handleRepaint()
819{
820    ATRACE_CALL();
821
822    // compute the invalid region
823    mSwapRegion.orSelf(mDirtyRegion);
824
825    if (CC_UNLIKELY(mDebugRegion)) {
826        debugFlashRegions();
827    }
828
829    // set the frame buffer
830    const DisplayHardware& hw(graphicPlane(0).displayHardware());
831    glMatrixMode(GL_MODELVIEW);
832    glLoadIdentity();
833
834    uint32_t flags = hw.getFlags();
835    if (flags & DisplayHardware::SWAP_RECTANGLE) {
836        // we can redraw only what's dirty, but since SWAP_RECTANGLE only
837        // takes a rectangle, we must make sure to update that whole
838        // rectangle in that case
839        mDirtyRegion.set(mSwapRegion.bounds());
840    } else {
841        if (flags & DisplayHardware::PARTIAL_UPDATES) {
842            // We need to redraw the rectangle that will be updated
843            // (pushed to the framebuffer).
844            // This is needed because PARTIAL_UPDATES only takes one
845            // rectangle instead of a region (see DisplayHardware::flip())
846            mDirtyRegion.set(mSwapRegion.bounds());
847        } else {
848            // we need to redraw everything (the whole screen)
849            mDirtyRegion.set(hw.bounds());
850            mSwapRegion = mDirtyRegion;
851        }
852    }
853
854    setupHardwareComposer();
855    composeSurfaces(mDirtyRegion);
856
857    // update the swap region and clear the dirty region
858    mSwapRegion.orSelf(mDirtyRegion);
859    mDirtyRegion.clear();
860}
861
862void SurfaceFlinger::setupHardwareComposer()
863{
864    const DisplayHardware& hw(graphicPlane(0).displayHardware());
865    HWComposer& hwc(hw.getHwComposer());
866
867    HWComposer::LayerListIterator cur = hwc.begin();
868    const HWComposer::LayerListIterator end = hwc.end();
869    if (cur == end) {
870        return;
871    }
872
873    const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
874    size_t count = layers.size();
875
876    ALOGE_IF(hwc.getNumLayers() != count,
877            "HAL number of layers (%d) doesn't match surfaceflinger (%d)",
878            hwc.getNumLayers(), count);
879
880    // just to be extra-safe, use the smallest count
881    if (hwc.initCheck() == NO_ERROR) {
882        count = count < hwc.getNumLayers() ? count : hwc.getNumLayers();
883    }
884
885    /*
886     *  update the per-frame h/w composer data for each layer
887     *  and build the transparent region of the FB
888     */
889    for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
890        const sp<LayerBase>& layer(layers[i]);
891        layer->setPerFrameData(*cur);
892    }
893    status_t err = hwc.prepare();
894    ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
895}
896
897void SurfaceFlinger::composeSurfaces(const Region& dirty)
898{
899    const DisplayHardware& hw(graphicPlane(0).displayHardware());
900    HWComposer& hwc(hw.getHwComposer());
901    HWComposer::LayerListIterator cur = hwc.begin();
902    const HWComposer::LayerListIterator end = hwc.end();
903
904    const size_t fbLayerCount = hwc.getLayerCount(HWC_FRAMEBUFFER);
905    if (cur==end || fbLayerCount) {
906        // Never touch the framebuffer if we don't have any framebuffer layers
907
908        if (hwc.getLayerCount(HWC_OVERLAY)) {
909            // when using overlays, we assume a fully transparent framebuffer
910            // NOTE: we could reduce how much we need to clear, for instance
911            // remove where there are opaque FB layers. however, on some
912            // GPUs doing a "clean slate" glClear might be more efficient.
913            // We'll revisit later if needed.
914            glClearColor(0, 0, 0, 0);
915            glClear(GL_COLOR_BUFFER_BIT);
916        } else {
917            // screen is already cleared here
918            if (!mWormholeRegion.isEmpty()) {
919                // can happen with SurfaceView
920                drawWormhole();
921            }
922        }
923
924        /*
925         * and then, render the layers targeted at the framebuffer
926         */
927
928        const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
929        const size_t count = layers.size();
930        for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
931            const sp<LayerBase>& layer(layers[i]);
932            const Region clip(dirty.intersect(layer->visibleRegionScreen));
933            if (!clip.isEmpty()) {
934                if (cur->getCompositionType() == HWC_OVERLAY) {
935                    if (i && (cur->getHints() & HWC_HINT_CLEAR_FB)
936                            && layer->isOpaque()) {
937                        // never clear the very first layer since we're
938                        // guaranteed the FB is already cleared
939                        layer->clearWithOpenGL(clip);
940                    }
941                    continue;
942                }
943                // render the layer
944                layer->draw(clip);
945            }
946        }
947    }
948}
949
950void SurfaceFlinger::debugFlashRegions()
951{
952    const DisplayHardware& hw(graphicPlane(0).displayHardware());
953    const uint32_t flags = hw.getFlags();
954    const int32_t height = hw.getHeight();
955    if (mSwapRegion.isEmpty()) {
956        return;
957    }
958
959    if (!(flags & DisplayHardware::SWAP_RECTANGLE)) {
960        const Region repaint((flags & DisplayHardware::PARTIAL_UPDATES) ?
961                mDirtyRegion.bounds() : hw.bounds());
962        composeSurfaces(repaint);
963    }
964
965    glDisable(GL_TEXTURE_EXTERNAL_OES);
966    glDisable(GL_TEXTURE_2D);
967    glDisable(GL_BLEND);
968
969    static int toggle = 0;
970    toggle = 1 - toggle;
971    if (toggle) {
972        glColor4f(1, 0, 1, 1);
973    } else {
974        glColor4f(1, 1, 0, 1);
975    }
976
977    Region::const_iterator it = mDirtyRegion.begin();
978    Region::const_iterator const end = mDirtyRegion.end();
979    while (it != end) {
980        const Rect& r = *it++;
981        GLfloat vertices[][2] = {
982                { r.left,  height - r.top },
983                { r.left,  height - r.bottom },
984                { r.right, height - r.bottom },
985                { r.right, height - r.top }
986        };
987        glVertexPointer(2, GL_FLOAT, 0, vertices);
988        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
989    }
990
991    hw.flip(mSwapRegion);
992
993    if (mDebugRegion > 1)
994        usleep(mDebugRegion * 1000);
995}
996
997void SurfaceFlinger::drawWormhole() const
998{
999    const Region region(mWormholeRegion.intersect(mDirtyRegion));
1000    if (region.isEmpty())
1001        return;
1002
1003    glDisable(GL_TEXTURE_EXTERNAL_OES);
1004    glDisable(GL_TEXTURE_2D);
1005    glDisable(GL_BLEND);
1006    glColor4f(0,0,0,0);
1007
1008    GLfloat vertices[4][2];
1009    glVertexPointer(2, GL_FLOAT, 0, vertices);
1010    Region::const_iterator it = region.begin();
1011    Region::const_iterator const end = region.end();
1012    while (it != end) {
1013        const Rect& r = *it++;
1014        vertices[0][0] = r.left;
1015        vertices[0][1] = r.top;
1016        vertices[1][0] = r.right;
1017        vertices[1][1] = r.top;
1018        vertices[2][0] = r.right;
1019        vertices[2][1] = r.bottom;
1020        vertices[3][0] = r.left;
1021        vertices[3][1] = r.bottom;
1022        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1023    }
1024}
1025
1026status_t SurfaceFlinger::addLayer(const sp<LayerBase>& layer)
1027{
1028    Mutex::Autolock _l(mStateLock);
1029    addLayer_l(layer);
1030    setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
1031    return NO_ERROR;
1032}
1033
1034status_t SurfaceFlinger::addLayer_l(const sp<LayerBase>& layer)
1035{
1036    ssize_t i = mCurrentState.layersSortedByZ.add(layer);
1037    return (i < 0) ? status_t(i) : status_t(NO_ERROR);
1038}
1039
1040ssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
1041        const sp<LayerBaseClient>& lbc)
1042{
1043    // attach this layer to the client
1044    size_t name = client->attachLayer(lbc);
1045
1046    Mutex::Autolock _l(mStateLock);
1047
1048    // add this layer to the current state list
1049    addLayer_l(lbc);
1050
1051    return ssize_t(name);
1052}
1053
1054status_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer)
1055{
1056    Mutex::Autolock _l(mStateLock);
1057    status_t err = purgatorizeLayer_l(layer);
1058    if (err == NO_ERROR)
1059        setTransactionFlags(eTransactionNeeded);
1060    return err;
1061}
1062
1063status_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase)
1064{
1065    sp<LayerBaseClient> lbc(layerBase->getLayerBaseClient());
1066    if (lbc != 0) {
1067        mLayerMap.removeItem( lbc->getSurfaceBinder() );
1068    }
1069    ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase);
1070    if (index >= 0) {
1071        mLayersRemoved = true;
1072        return NO_ERROR;
1073    }
1074    return status_t(index);
1075}
1076
1077status_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase)
1078{
1079    // First add the layer to the purgatory list, which makes sure it won't
1080    // go away, then remove it from the main list (through a transaction).
1081    ssize_t err = removeLayer_l(layerBase);
1082    if (err >= 0) {
1083        mLayerPurgatory.add(layerBase);
1084    }
1085
1086    mLayersPendingRemoval.push(layerBase);
1087
1088    // it's possible that we don't find a layer, because it might
1089    // have been destroyed already -- this is not technically an error
1090    // from the user because there is a race between Client::destroySurface(),
1091    // ~Client() and ~ISurface().
1092    return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err;
1093}
1094
1095status_t SurfaceFlinger::invalidateLayerVisibility(const sp<LayerBase>& layer)
1096{
1097    layer->forceVisibilityTransaction();
1098    setTransactionFlags(eTraversalNeeded);
1099    return NO_ERROR;
1100}
1101
1102uint32_t SurfaceFlinger::peekTransactionFlags(uint32_t flags)
1103{
1104    return android_atomic_release_load(&mTransactionFlags);
1105}
1106
1107uint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags)
1108{
1109    return android_atomic_and(~flags, &mTransactionFlags) & flags;
1110}
1111
1112uint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags)
1113{
1114    uint32_t old = android_atomic_or(flags, &mTransactionFlags);
1115    if ((old & flags)==0) { // wake the server up
1116        signalTransaction();
1117    }
1118    return old;
1119}
1120
1121
1122void SurfaceFlinger::setTransactionState(const Vector<ComposerState>& state,
1123        int orientation, uint32_t flags) {
1124    Mutex::Autolock _l(mStateLock);
1125
1126    uint32_t transactionFlags = 0;
1127    if (mCurrentState.orientation != orientation) {
1128        if (uint32_t(orientation)<=eOrientation270 || orientation==42) {
1129            mCurrentState.orientation = orientation;
1130            transactionFlags |= eTransactionNeeded;
1131        } else if (orientation != eOrientationUnchanged) {
1132            ALOGW("setTransactionState: ignoring unrecognized orientation: %d",
1133                    orientation);
1134        }
1135    }
1136
1137    const size_t count = state.size();
1138    for (size_t i=0 ; i<count ; i++) {
1139        const ComposerState& s(state[i]);
1140        sp<Client> client( static_cast<Client *>(s.client.get()) );
1141        transactionFlags |= setClientStateLocked(client, s.state);
1142    }
1143
1144    if (transactionFlags) {
1145        // this triggers the transaction
1146        setTransactionFlags(transactionFlags);
1147
1148        // if this is a synchronous transaction, wait for it to take effect
1149        // before returning.
1150        if (flags & eSynchronous) {
1151            mTransationPending = true;
1152        }
1153        while (mTransationPending) {
1154            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
1155            if (CC_UNLIKELY(err != NO_ERROR)) {
1156                // just in case something goes wrong in SF, return to the
1157                // called after a few seconds.
1158                ALOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!");
1159                mTransationPending = false;
1160                break;
1161            }
1162        }
1163    }
1164}
1165
1166sp<ISurface> SurfaceFlinger::createSurface(
1167        ISurfaceComposerClient::surface_data_t* params,
1168        const String8& name,
1169        const sp<Client>& client,
1170        DisplayID d, uint32_t w, uint32_t h, PixelFormat format,
1171        uint32_t flags)
1172{
1173    sp<LayerBaseClient> layer;
1174    sp<ISurface> surfaceHandle;
1175
1176    if (int32_t(w|h) < 0) {
1177        ALOGE("createSurface() failed, w or h is negative (w=%d, h=%d)",
1178                int(w), int(h));
1179        return surfaceHandle;
1180    }
1181
1182    //ALOGD("createSurface for (%d x %d), name=%s", w, h, name.string());
1183    sp<Layer> normalLayer;
1184    switch (flags & eFXSurfaceMask) {
1185        case eFXSurfaceNormal:
1186            normalLayer = createNormalSurface(client, d, w, h, flags, format);
1187            layer = normalLayer;
1188            break;
1189        case eFXSurfaceBlur:
1190            // for now we treat Blur as Dim, until we can implement it
1191            // efficiently.
1192        case eFXSurfaceDim:
1193            layer = createDimSurface(client, d, w, h, flags);
1194            break;
1195        case eFXSurfaceScreenshot:
1196            layer = createScreenshotSurface(client, d, w, h, flags);
1197            break;
1198    }
1199
1200    if (layer != 0) {
1201        layer->initStates(w, h, flags);
1202        layer->setName(name);
1203        ssize_t token = addClientLayer(client, layer);
1204
1205        surfaceHandle = layer->getSurface();
1206        if (surfaceHandle != 0) {
1207            params->token = token;
1208            params->identity = layer->getIdentity();
1209            if (normalLayer != 0) {
1210                Mutex::Autolock _l(mStateLock);
1211                mLayerMap.add(layer->getSurfaceBinder(), normalLayer);
1212            }
1213        }
1214
1215        setTransactionFlags(eTransactionNeeded);
1216    }
1217
1218    return surfaceHandle;
1219}
1220
1221sp<Layer> SurfaceFlinger::createNormalSurface(
1222        const sp<Client>& client, DisplayID display,
1223        uint32_t w, uint32_t h, uint32_t flags,
1224        PixelFormat& format)
1225{
1226    // initialize the surfaces
1227    switch (format) { // TODO: take h/w into account
1228    case PIXEL_FORMAT_TRANSPARENT:
1229    case PIXEL_FORMAT_TRANSLUCENT:
1230        format = PIXEL_FORMAT_RGBA_8888;
1231        break;
1232    case PIXEL_FORMAT_OPAQUE:
1233#ifdef NO_RGBX_8888
1234        format = PIXEL_FORMAT_RGB_565;
1235#else
1236        format = PIXEL_FORMAT_RGBX_8888;
1237#endif
1238        break;
1239    }
1240
1241#ifdef NO_RGBX_8888
1242    if (format == PIXEL_FORMAT_RGBX_8888)
1243        format = PIXEL_FORMAT_RGBA_8888;
1244#endif
1245
1246    sp<Layer> layer = new Layer(this, display, client);
1247    status_t err = layer->setBuffers(w, h, format, flags);
1248    if (CC_LIKELY(err != NO_ERROR)) {
1249        ALOGE("createNormalSurfaceLocked() failed (%s)", strerror(-err));
1250        layer.clear();
1251    }
1252    return layer;
1253}
1254
1255sp<LayerDim> SurfaceFlinger::createDimSurface(
1256        const sp<Client>& client, DisplayID display,
1257        uint32_t w, uint32_t h, uint32_t flags)
1258{
1259    sp<LayerDim> layer = new LayerDim(this, display, client);
1260    return layer;
1261}
1262
1263sp<LayerScreenshot> SurfaceFlinger::createScreenshotSurface(
1264        const sp<Client>& client, DisplayID display,
1265        uint32_t w, uint32_t h, uint32_t flags)
1266{
1267    sp<LayerScreenshot> layer = new LayerScreenshot(this, display, client);
1268    return layer;
1269}
1270
1271status_t SurfaceFlinger::removeSurface(const sp<Client>& client, SurfaceID sid)
1272{
1273    /*
1274     * called by the window manager, when a surface should be marked for
1275     * destruction.
1276     *
1277     * The surface is removed from the current and drawing lists, but placed
1278     * in the purgatory queue, so it's not destroyed right-away (we need
1279     * to wait for all client's references to go away first).
1280     */
1281
1282    status_t err = NAME_NOT_FOUND;
1283    Mutex::Autolock _l(mStateLock);
1284    sp<LayerBaseClient> layer = client->getLayerUser(sid);
1285
1286    if (layer != 0) {
1287        err = purgatorizeLayer_l(layer);
1288        if (err == NO_ERROR) {
1289            setTransactionFlags(eTransactionNeeded);
1290        }
1291    }
1292    return err;
1293}
1294
1295status_t SurfaceFlinger::destroySurface(const wp<LayerBaseClient>& layer)
1296{
1297    // called by ~ISurface() when all references are gone
1298    status_t err = NO_ERROR;
1299    sp<LayerBaseClient> l(layer.promote());
1300    if (l != NULL) {
1301        Mutex::Autolock _l(mStateLock);
1302        err = removeLayer_l(l);
1303        if (err == NAME_NOT_FOUND) {
1304            // The surface wasn't in the current list, which means it was
1305            // removed already, which means it is in the purgatory,
1306            // and need to be removed from there.
1307            ssize_t idx = mLayerPurgatory.remove(l);
1308            ALOGE_IF(idx < 0,
1309                    "layer=%p is not in the purgatory list", l.get());
1310        }
1311        ALOGE_IF(err<0 && err != NAME_NOT_FOUND,
1312                "error removing layer=%p (%s)", l.get(), strerror(-err));
1313    }
1314    return err;
1315}
1316
1317uint32_t SurfaceFlinger::setClientStateLocked(
1318        const sp<Client>& client,
1319        const layer_state_t& s)
1320{
1321    uint32_t flags = 0;
1322    sp<LayerBaseClient> layer(client->getLayerUser(s.surface));
1323    if (layer != 0) {
1324        const uint32_t what = s.what;
1325        if (what & ePositionChanged) {
1326            if (layer->setPosition(s.x, s.y))
1327                flags |= eTraversalNeeded;
1328        }
1329        if (what & eLayerChanged) {
1330            ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
1331            if (layer->setLayer(s.z)) {
1332                mCurrentState.layersSortedByZ.removeAt(idx);
1333                mCurrentState.layersSortedByZ.add(layer);
1334                // we need traversal (state changed)
1335                // AND transaction (list changed)
1336                flags |= eTransactionNeeded|eTraversalNeeded;
1337            }
1338        }
1339        if (what & eSizeChanged) {
1340            if (layer->setSize(s.w, s.h)) {
1341                flags |= eTraversalNeeded;
1342            }
1343        }
1344        if (what & eAlphaChanged) {
1345            if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f)))
1346                flags |= eTraversalNeeded;
1347        }
1348        if (what & eMatrixChanged) {
1349            if (layer->setMatrix(s.matrix))
1350                flags |= eTraversalNeeded;
1351        }
1352        if (what & eTransparentRegionChanged) {
1353            if (layer->setTransparentRegionHint(s.transparentRegion))
1354                flags |= eTraversalNeeded;
1355        }
1356        if (what & eVisibilityChanged) {
1357            if (layer->setFlags(s.flags, s.mask))
1358                flags |= eTraversalNeeded;
1359        }
1360        if (what & eCropChanged) {
1361            if (layer->setCrop(s.crop))
1362                flags |= eTraversalNeeded;
1363        }
1364    }
1365    return flags;
1366}
1367
1368// ---------------------------------------------------------------------------
1369
1370void SurfaceFlinger::onScreenAcquired() {
1371    ALOGD("Screen about to return, flinger = %p", this);
1372    const DisplayHardware& hw(graphicPlane(0).displayHardware());
1373    hw.acquireScreen();
1374    mEventThread->onScreenAcquired();
1375    // this is a temporary work-around, eventually this should be called
1376    // by the power-manager
1377    SurfaceFlinger::turnElectronBeamOn(mElectronBeamAnimationMode);
1378    // from this point on, SF will process updates again
1379    repaintEverything();
1380}
1381
1382void SurfaceFlinger::onScreenReleased() {
1383    ALOGD("About to give-up screen, flinger = %p", this);
1384    const DisplayHardware& hw(graphicPlane(0).displayHardware());
1385    if (hw.isScreenAcquired()) {
1386        mEventThread->onScreenReleased();
1387        hw.releaseScreen();
1388        // from this point on, SF will stop drawing
1389    }
1390}
1391
1392void SurfaceFlinger::unblank() {
1393    class MessageScreenAcquired : public MessageBase {
1394        SurfaceFlinger* flinger;
1395    public:
1396        MessageScreenAcquired(SurfaceFlinger* flinger) : flinger(flinger) { }
1397        virtual bool handler() {
1398            flinger->onScreenAcquired();
1399            return true;
1400        }
1401    };
1402    sp<MessageBase> msg = new MessageScreenAcquired(this);
1403    postMessageSync(msg);
1404}
1405
1406void SurfaceFlinger::blank() {
1407    class MessageScreenReleased : public MessageBase {
1408        SurfaceFlinger* flinger;
1409    public:
1410        MessageScreenReleased(SurfaceFlinger* flinger) : flinger(flinger) { }
1411        virtual bool handler() {
1412            flinger->onScreenReleased();
1413            return true;
1414        }
1415    };
1416    sp<MessageBase> msg = new MessageScreenReleased(this);
1417    postMessageSync(msg);
1418}
1419
1420// ---------------------------------------------------------------------------
1421
1422status_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
1423{
1424    const size_t SIZE = 4096;
1425    char buffer[SIZE];
1426    String8 result;
1427
1428    if (!PermissionCache::checkCallingPermission(sDump)) {
1429        snprintf(buffer, SIZE, "Permission Denial: "
1430                "can't dump SurfaceFlinger from pid=%d, uid=%d\n",
1431                IPCThreadState::self()->getCallingPid(),
1432                IPCThreadState::self()->getCallingUid());
1433        result.append(buffer);
1434    } else {
1435        // Try to get the main lock, but don't insist if we can't
1436        // (this would indicate SF is stuck, but we want to be able to
1437        // print something in dumpsys).
1438        int retry = 3;
1439        while (mStateLock.tryLock()<0 && --retry>=0) {
1440            usleep(1000000);
1441        }
1442        const bool locked(retry >= 0);
1443        if (!locked) {
1444            snprintf(buffer, SIZE,
1445                    "SurfaceFlinger appears to be unresponsive, "
1446                    "dumping anyways (no locks held)\n");
1447            result.append(buffer);
1448        }
1449
1450        bool dumpAll = true;
1451        size_t index = 0;
1452        size_t numArgs = args.size();
1453        if (numArgs) {
1454            if ((index < numArgs) &&
1455                    (args[index] == String16("--list"))) {
1456                index++;
1457                listLayersLocked(args, index, result, buffer, SIZE);
1458                dumpAll = false;
1459            }
1460
1461            if ((index < numArgs) &&
1462                    (args[index] == String16("--latency"))) {
1463                index++;
1464                dumpStatsLocked(args, index, result, buffer, SIZE);
1465                dumpAll = false;
1466            }
1467
1468            if ((index < numArgs) &&
1469                    (args[index] == String16("--latency-clear"))) {
1470                index++;
1471                clearStatsLocked(args, index, result, buffer, SIZE);
1472                dumpAll = false;
1473            }
1474        }
1475
1476        if (dumpAll) {
1477            dumpAllLocked(result, buffer, SIZE);
1478        }
1479
1480        if (locked) {
1481            mStateLock.unlock();
1482        }
1483    }
1484    write(fd, result.string(), result.size());
1485    return NO_ERROR;
1486}
1487
1488void SurfaceFlinger::listLayersLocked(const Vector<String16>& args, size_t& index,
1489        String8& result, char* buffer, size_t SIZE) const
1490{
1491    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
1492    const size_t count = currentLayers.size();
1493    for (size_t i=0 ; i<count ; i++) {
1494        const sp<LayerBase>& layer(currentLayers[i]);
1495        snprintf(buffer, SIZE, "%s\n", layer->getName().string());
1496        result.append(buffer);
1497    }
1498}
1499
1500void SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index,
1501        String8& result, char* buffer, size_t SIZE) const
1502{
1503    String8 name;
1504    if (index < args.size()) {
1505        name = String8(args[index]);
1506        index++;
1507    }
1508
1509    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
1510    const size_t count = currentLayers.size();
1511    for (size_t i=0 ; i<count ; i++) {
1512        const sp<LayerBase>& layer(currentLayers[i]);
1513        if (name.isEmpty()) {
1514            snprintf(buffer, SIZE, "%s\n", layer->getName().string());
1515            result.append(buffer);
1516        }
1517        if (name.isEmpty() || (name == layer->getName())) {
1518            layer->dumpStats(result, buffer, SIZE);
1519        }
1520    }
1521}
1522
1523void SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& index,
1524        String8& result, char* buffer, size_t SIZE) const
1525{
1526    String8 name;
1527    if (index < args.size()) {
1528        name = String8(args[index]);
1529        index++;
1530    }
1531
1532    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
1533    const size_t count = currentLayers.size();
1534    for (size_t i=0 ; i<count ; i++) {
1535        const sp<LayerBase>& layer(currentLayers[i]);
1536        if (name.isEmpty() || (name == layer->getName())) {
1537            layer->clearStats();
1538        }
1539    }
1540}
1541
1542void SurfaceFlinger::dumpAllLocked(
1543        String8& result, char* buffer, size_t SIZE) const
1544{
1545    // figure out if we're stuck somewhere
1546    const nsecs_t now = systemTime();
1547    const nsecs_t inSwapBuffers(mDebugInSwapBuffers);
1548    const nsecs_t inTransaction(mDebugInTransaction);
1549    nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0;
1550    nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0;
1551
1552    /*
1553     * Dump the visible layer list
1554     */
1555    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
1556    const size_t count = currentLayers.size();
1557    snprintf(buffer, SIZE, "Visible layers (count = %d)\n", count);
1558    result.append(buffer);
1559    for (size_t i=0 ; i<count ; i++) {
1560        const sp<LayerBase>& layer(currentLayers[i]);
1561        layer->dump(result, buffer, SIZE);
1562    }
1563
1564    /*
1565     * Dump the layers in the purgatory
1566     */
1567
1568    const size_t purgatorySize = mLayerPurgatory.size();
1569    snprintf(buffer, SIZE, "Purgatory state (%d entries)\n", purgatorySize);
1570    result.append(buffer);
1571    for (size_t i=0 ; i<purgatorySize ; i++) {
1572        const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
1573        layer->shortDump(result, buffer, SIZE);
1574    }
1575
1576    /*
1577     * Dump SurfaceFlinger global state
1578     */
1579
1580    snprintf(buffer, SIZE, "SurfaceFlinger global state:\n");
1581    result.append(buffer);
1582
1583    const GLExtensions& extensions(GLExtensions::getInstance());
1584    snprintf(buffer, SIZE, "GLES: %s, %s, %s\n",
1585            extensions.getVendor(),
1586            extensions.getRenderer(),
1587            extensions.getVersion());
1588    result.append(buffer);
1589
1590    snprintf(buffer, SIZE, "EGL : %s\n",
1591            eglQueryString(graphicPlane(0).getEGLDisplay(),
1592                    EGL_VERSION_HW_ANDROID));
1593    result.append(buffer);
1594
1595    snprintf(buffer, SIZE, "EXTS: %s\n", extensions.getExtension());
1596    result.append(buffer);
1597
1598    mWormholeRegion.dump(result, "WormholeRegion");
1599    const DisplayHardware& hw(graphicPlane(0).displayHardware());
1600    snprintf(buffer, SIZE,
1601            "  orientation=%d, canDraw=%d\n",
1602            mCurrentState.orientation, hw.canDraw());
1603    result.append(buffer);
1604    snprintf(buffer, SIZE,
1605            "  last eglSwapBuffers() time: %f us\n"
1606            "  last transaction time     : %f us\n"
1607            "  transaction-flags         : %08x\n"
1608            "  refresh-rate              : %f fps\n"
1609            "  x-dpi                     : %f\n"
1610            "  y-dpi                     : %f\n"
1611            "  density                   : %f\n",
1612            mLastSwapBufferTime/1000.0,
1613            mLastTransactionTime/1000.0,
1614            mTransactionFlags,
1615            hw.getRefreshRate(),
1616            hw.getDpiX(),
1617            hw.getDpiY(),
1618            hw.getDensity());
1619    result.append(buffer);
1620
1621    snprintf(buffer, SIZE, "  eglSwapBuffers time: %f us\n",
1622            inSwapBuffersDuration/1000.0);
1623    result.append(buffer);
1624
1625    snprintf(buffer, SIZE, "  transaction time: %f us\n",
1626            inTransactionDuration/1000.0);
1627    result.append(buffer);
1628
1629    /*
1630     * VSYNC state
1631     */
1632    mEventThread->dump(result, buffer, SIZE);
1633
1634    /*
1635     * Dump HWComposer state
1636     */
1637    HWComposer& hwc(hw.getHwComposer());
1638    snprintf(buffer, SIZE, "h/w composer state:\n");
1639    result.append(buffer);
1640    snprintf(buffer, SIZE, "  h/w composer %s and %s\n",
1641            hwc.initCheck()==NO_ERROR ? "present" : "not present",
1642                    (mDebugDisableHWC || mDebugRegion) ? "disabled" : "enabled");
1643    result.append(buffer);
1644    hwc.dump(result, buffer, SIZE, mVisibleLayersSortedByZ);
1645
1646    /*
1647     * Dump gralloc state
1648     */
1649    const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
1650    alloc.dump(result);
1651    hw.dump(result);
1652}
1653
1654status_t SurfaceFlinger::onTransact(
1655    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
1656{
1657    switch (code) {
1658        case CREATE_CONNECTION:
1659        case SET_TRANSACTION_STATE:
1660        case SET_ORIENTATION:
1661        case BOOT_FINISHED:
1662        case TURN_ELECTRON_BEAM_OFF:
1663        case TURN_ELECTRON_BEAM_ON:
1664        case BLANK:
1665        case UNBLANK:
1666        {
1667            // codes that require permission check
1668            IPCThreadState* ipc = IPCThreadState::self();
1669            const int pid = ipc->getCallingPid();
1670            const int uid = ipc->getCallingUid();
1671            if ((uid != AID_GRAPHICS) &&
1672                    !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) {
1673                ALOGE("Permission Denial: "
1674                        "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
1675                return PERMISSION_DENIED;
1676            }
1677            break;
1678        }
1679        case CAPTURE_SCREEN:
1680        {
1681            // codes that require permission check
1682            IPCThreadState* ipc = IPCThreadState::self();
1683            const int pid = ipc->getCallingPid();
1684            const int uid = ipc->getCallingUid();
1685            if ((uid != AID_GRAPHICS) &&
1686                    !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) {
1687                ALOGE("Permission Denial: "
1688                        "can't read framebuffer pid=%d, uid=%d", pid, uid);
1689                return PERMISSION_DENIED;
1690            }
1691            break;
1692        }
1693    }
1694
1695    status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
1696    if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
1697        CHECK_INTERFACE(ISurfaceComposer, data, reply);
1698        if (CC_UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) {
1699            IPCThreadState* ipc = IPCThreadState::self();
1700            const int pid = ipc->getCallingPid();
1701            const int uid = ipc->getCallingUid();
1702            ALOGE("Permission Denial: "
1703                    "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
1704            return PERMISSION_DENIED;
1705        }
1706        int n;
1707        switch (code) {
1708            case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE
1709            case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE
1710                return NO_ERROR;
1711            case 1002:  // SHOW_UPDATES
1712                n = data.readInt32();
1713                mDebugRegion = n ? n : (mDebugRegion ? 0 : 1);
1714                invalidateHwcGeometry();
1715                repaintEverything();
1716                return NO_ERROR;
1717            case 1004:{ // repaint everything
1718                repaintEverything();
1719                return NO_ERROR;
1720            }
1721            case 1005:{ // force transaction
1722                setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
1723                return NO_ERROR;
1724            }
1725            case 1006:{ // send empty update
1726                signalRefresh();
1727                return NO_ERROR;
1728            }
1729            case 1008:  // toggle use of hw composer
1730                n = data.readInt32();
1731                mDebugDisableHWC = n ? 1 : 0;
1732                invalidateHwcGeometry();
1733                repaintEverything();
1734                return NO_ERROR;
1735            case 1009:  // toggle use of transform hint
1736                n = data.readInt32();
1737                mDebugDisableTransformHint = n ? 1 : 0;
1738                invalidateHwcGeometry();
1739                repaintEverything();
1740                return NO_ERROR;
1741            case 1010:  // interrogate.
1742                reply->writeInt32(0);
1743                reply->writeInt32(0);
1744                reply->writeInt32(mDebugRegion);
1745                reply->writeInt32(0);
1746                reply->writeInt32(mDebugDisableHWC);
1747                return NO_ERROR;
1748            case 1013: {
1749                Mutex::Autolock _l(mStateLock);
1750                const DisplayHardware& hw(graphicPlane(0).displayHardware());
1751                reply->writeInt32(hw.getPageFlipCount());
1752            }
1753            return NO_ERROR;
1754        }
1755    }
1756    return err;
1757}
1758
1759void SurfaceFlinger::repaintEverything() {
1760    const DisplayHardware& hw(graphicPlane(0).displayHardware());
1761    const Rect bounds(hw.getBounds());
1762    setInvalidateRegion(Region(bounds));
1763    signalTransaction();
1764}
1765
1766void SurfaceFlinger::setInvalidateRegion(const Region& reg) {
1767    Mutex::Autolock _l(mInvalidateLock);
1768    mInvalidateRegion = reg;
1769}
1770
1771Region SurfaceFlinger::getAndClearInvalidateRegion() {
1772    Mutex::Autolock _l(mInvalidateLock);
1773    Region reg(mInvalidateRegion);
1774    mInvalidateRegion.clear();
1775    return reg;
1776}
1777
1778// ---------------------------------------------------------------------------
1779
1780status_t SurfaceFlinger::renderScreenToTexture(DisplayID dpy,
1781        GLuint* textureName, GLfloat* uOut, GLfloat* vOut)
1782{
1783    Mutex::Autolock _l(mStateLock);
1784    return renderScreenToTextureLocked(dpy, textureName, uOut, vOut);
1785}
1786
1787status_t SurfaceFlinger::renderScreenToTextureLocked(DisplayID dpy,
1788        GLuint* textureName, GLfloat* uOut, GLfloat* vOut)
1789{
1790    ATRACE_CALL();
1791
1792    if (!GLExtensions::getInstance().haveFramebufferObject())
1793        return INVALID_OPERATION;
1794
1795    // get screen geometry
1796    const DisplayHardware& hw(graphicPlane(dpy).displayHardware());
1797    const uint32_t hw_w = hw.getWidth();
1798    const uint32_t hw_h = hw.getHeight();
1799    GLfloat u = 1;
1800    GLfloat v = 1;
1801
1802    // make sure to clear all GL error flags
1803    while ( glGetError() != GL_NO_ERROR ) ;
1804
1805    // create a FBO
1806    GLuint name, tname;
1807    glGenTextures(1, &tname);
1808    glBindTexture(GL_TEXTURE_2D, tname);
1809    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1810    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1811    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
1812            hw_w, hw_h, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
1813    if (glGetError() != GL_NO_ERROR) {
1814        while ( glGetError() != GL_NO_ERROR ) ;
1815        GLint tw = (2 << (31 - clz(hw_w)));
1816        GLint th = (2 << (31 - clz(hw_h)));
1817        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
1818                tw, th, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
1819        u = GLfloat(hw_w) / tw;
1820        v = GLfloat(hw_h) / th;
1821    }
1822    glGenFramebuffersOES(1, &name);
1823    glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
1824    glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES,
1825            GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0);
1826
1827    // redraw the screen entirely...
1828    glDisable(GL_TEXTURE_EXTERNAL_OES);
1829    glDisable(GL_TEXTURE_2D);
1830    glClearColor(0,0,0,1);
1831    glClear(GL_COLOR_BUFFER_BIT);
1832    glMatrixMode(GL_MODELVIEW);
1833    glLoadIdentity();
1834    const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
1835    const size_t count = layers.size();
1836    for (size_t i=0 ; i<count ; ++i) {
1837        const sp<LayerBase>& layer(layers[i]);
1838        layer->drawForSreenShot();
1839    }
1840
1841    hw.compositionComplete();
1842
1843    // back to main framebuffer
1844    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
1845    glDeleteFramebuffersOES(1, &name);
1846
1847    *textureName = tname;
1848    *uOut = u;
1849    *vOut = v;
1850    return NO_ERROR;
1851}
1852
1853// ---------------------------------------------------------------------------
1854
1855class VSyncWaiter {
1856    DisplayEventReceiver::Event buffer[4];
1857    sp<Looper> looper;
1858    sp<IDisplayEventConnection> events;
1859    sp<BitTube> eventTube;
1860public:
1861    VSyncWaiter(const sp<EventThread>& eventThread) {
1862        looper = new Looper(true);
1863        events = eventThread->createEventConnection();
1864        eventTube = events->getDataChannel();
1865        looper->addFd(eventTube->getFd(), 0, ALOOPER_EVENT_INPUT, 0, 0);
1866        events->requestNextVsync();
1867    }
1868
1869    void wait() {
1870        ssize_t n;
1871
1872        looper->pollOnce(-1);
1873        // we don't handle any errors here, it doesn't matter
1874        // and we don't want to take the risk to get stuck.
1875
1876        // drain the events...
1877        while ((n = DisplayEventReceiver::getEvents(
1878                eventTube, buffer, 4)) > 0) ;
1879
1880        events->requestNextVsync();
1881    }
1882};
1883
1884status_t SurfaceFlinger::electronBeamOffAnimationImplLocked()
1885{
1886    // get screen geometry
1887    const DisplayHardware& hw(graphicPlane(0).displayHardware());
1888    const uint32_t hw_w = hw.getWidth();
1889    const uint32_t hw_h = hw.getHeight();
1890    const Region screenBounds(hw.getBounds());
1891
1892    GLfloat u, v;
1893    GLuint tname;
1894    status_t result = renderScreenToTextureLocked(0, &tname, &u, &v);
1895    if (result != NO_ERROR) {
1896        return result;
1897    }
1898
1899    GLfloat vtx[8];
1900    const GLfloat texCoords[4][2] = { {0,0}, {0,v}, {u,v}, {u,0} };
1901    glBindTexture(GL_TEXTURE_2D, tname);
1902    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1903    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1904    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1905    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1906    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1907    glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
1908    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
1909    glVertexPointer(2, GL_FLOAT, 0, vtx);
1910
1911    /*
1912     * Texture coordinate mapping
1913     *
1914     *                 u
1915     *    1 +----------+---+
1916     *      |     |    |   |  image is inverted
1917     *      |     V    |   |  w.r.t. the texture
1918     *  1-v +----------+   |  coordinates
1919     *      |              |
1920     *      |              |
1921     *      |              |
1922     *    0 +--------------+
1923     *      0              1
1924     *
1925     */
1926
1927    class s_curve_interpolator {
1928        const float nbFrames, s, v;
1929    public:
1930        s_curve_interpolator(int nbFrames, float s)
1931        : nbFrames(1.0f / (nbFrames-1)), s(s),
1932          v(1.0f + expf(-s + 0.5f*s)) {
1933        }
1934        float operator()(int f) {
1935            const float x = f * nbFrames;
1936            return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f;
1937        }
1938    };
1939
1940    class v_stretch {
1941        const GLfloat hw_w, hw_h;
1942    public:
1943        v_stretch(uint32_t hw_w, uint32_t hw_h)
1944        : hw_w(hw_w), hw_h(hw_h) {
1945        }
1946        void operator()(GLfloat* vtx, float v) {
1947            const GLfloat w = hw_w + (hw_w * v);
1948            const GLfloat h = hw_h - (hw_h * v);
1949            const GLfloat x = (hw_w - w) * 0.5f;
1950            const GLfloat y = (hw_h - h) * 0.5f;
1951            vtx[0] = x;         vtx[1] = y;
1952            vtx[2] = x;         vtx[3] = y + h;
1953            vtx[4] = x + w;     vtx[5] = y + h;
1954            vtx[6] = x + w;     vtx[7] = y;
1955        }
1956    };
1957
1958    class h_stretch {
1959        const GLfloat hw_w, hw_h;
1960    public:
1961        h_stretch(uint32_t hw_w, uint32_t hw_h)
1962        : hw_w(hw_w), hw_h(hw_h) {
1963        }
1964        void operator()(GLfloat* vtx, float v) {
1965            const GLfloat w = hw_w - (hw_w * v);
1966            const GLfloat h = 1.0f;
1967            const GLfloat x = (hw_w - w) * 0.5f;
1968            const GLfloat y = (hw_h - h) * 0.5f;
1969            vtx[0] = x;         vtx[1] = y;
1970            vtx[2] = x;         vtx[3] = y + h;
1971            vtx[4] = x + w;     vtx[5] = y + h;
1972            vtx[6] = x + w;     vtx[7] = y;
1973        }
1974    };
1975
1976    VSyncWaiter vsync(mEventThread);
1977
1978    // the full animation is 24 frames
1979    char value[PROPERTY_VALUE_MAX];
1980    property_get("debug.sf.electron_frames", value, "24");
1981    int nbFrames = (atoi(value) + 1) >> 1;
1982    if (nbFrames <= 0) // just in case
1983        nbFrames = 24;
1984
1985    s_curve_interpolator itr(nbFrames, 7.5f);
1986    s_curve_interpolator itg(nbFrames, 8.0f);
1987    s_curve_interpolator itb(nbFrames, 8.5f);
1988
1989    v_stretch vverts(hw_w, hw_h);
1990
1991    glMatrixMode(GL_TEXTURE);
1992    glLoadIdentity();
1993    glMatrixMode(GL_MODELVIEW);
1994    glLoadIdentity();
1995
1996    glEnable(GL_BLEND);
1997    glBlendFunc(GL_ONE, GL_ONE);
1998    for (int i=0 ; i<nbFrames ; i++) {
1999        float x, y, w, h;
2000        const float vr = itr(i);
2001        const float vg = itg(i);
2002        const float vb = itb(i);
2003
2004        // wait for vsync
2005        vsync.wait();
2006
2007        // clear screen
2008        glColorMask(1,1,1,1);
2009        glClear(GL_COLOR_BUFFER_BIT);
2010        glEnable(GL_TEXTURE_2D);
2011
2012        // draw the red plane
2013        vverts(vtx, vr);
2014        glColorMask(1,0,0,1);
2015        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
2016
2017        // draw the green plane
2018        vverts(vtx, vg);
2019        glColorMask(0,1,0,1);
2020        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
2021
2022        // draw the blue plane
2023        vverts(vtx, vb);
2024        glColorMask(0,0,1,1);
2025        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
2026
2027        // draw the white highlight (we use the last vertices)
2028        glDisable(GL_TEXTURE_2D);
2029        glColorMask(1,1,1,1);
2030        glColor4f(vg, vg, vg, 1);
2031        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
2032        hw.flip(screenBounds);
2033    }
2034
2035    h_stretch hverts(hw_w, hw_h);
2036    glDisable(GL_BLEND);
2037    glDisable(GL_TEXTURE_2D);
2038    glColorMask(1,1,1,1);
2039    for (int i=0 ; i<nbFrames ; i++) {
2040        const float v = itg(i);
2041        hverts(vtx, v);
2042
2043        // wait for vsync
2044        vsync.wait();
2045
2046        glClear(GL_COLOR_BUFFER_BIT);
2047        glColor4f(1-v, 1-v, 1-v, 1);
2048        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
2049        hw.flip(screenBounds);
2050    }
2051
2052    glColorMask(1,1,1,1);
2053    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
2054    glDeleteTextures(1, &tname);
2055    glDisable(GL_TEXTURE_2D);
2056    glDisable(GL_BLEND);
2057    return NO_ERROR;
2058}
2059
2060status_t SurfaceFlinger::electronBeamOnAnimationImplLocked()
2061{
2062    status_t result = PERMISSION_DENIED;
2063
2064    if (!GLExtensions::getInstance().haveFramebufferObject())
2065        return INVALID_OPERATION;
2066
2067
2068    // get screen geometry
2069    const DisplayHardware& hw(graphicPlane(0).displayHardware());
2070    const uint32_t hw_w = hw.getWidth();
2071    const uint32_t hw_h = hw.getHeight();
2072    const Region screenBounds(hw.bounds());
2073
2074    GLfloat u, v;
2075    GLuint tname;
2076    result = renderScreenToTextureLocked(0, &tname, &u, &v);
2077    if (result != NO_ERROR) {
2078        return result;
2079    }
2080
2081    GLfloat vtx[8];
2082    const GLfloat texCoords[4][2] = { {0,v}, {0,0}, {u,0}, {u,v} };
2083    glBindTexture(GL_TEXTURE_2D, tname);
2084    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
2085    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2086    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2087    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2088    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2089    glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
2090    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
2091    glVertexPointer(2, GL_FLOAT, 0, vtx);
2092
2093    class s_curve_interpolator {
2094        const float nbFrames, s, v;
2095    public:
2096        s_curve_interpolator(int nbFrames, float s)
2097        : nbFrames(1.0f / (nbFrames-1)), s(s),
2098          v(1.0f + expf(-s + 0.5f*s)) {
2099        }
2100        float operator()(int f) {
2101            const float x = f * nbFrames;
2102            return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f;
2103        }
2104    };
2105
2106    class v_stretch {
2107        const GLfloat hw_w, hw_h;
2108    public:
2109        v_stretch(uint32_t hw_w, uint32_t hw_h)
2110        : hw_w(hw_w), hw_h(hw_h) {
2111        }
2112        void operator()(GLfloat* vtx, float v) {
2113            const GLfloat w = hw_w + (hw_w * v);
2114            const GLfloat h = hw_h - (hw_h * v);
2115            const GLfloat x = (hw_w - w) * 0.5f;
2116            const GLfloat y = (hw_h - h) * 0.5f;
2117            vtx[0] = x;         vtx[1] = y;
2118            vtx[2] = x;         vtx[3] = y + h;
2119            vtx[4] = x + w;     vtx[5] = y + h;
2120            vtx[6] = x + w;     vtx[7] = y;
2121        }
2122    };
2123
2124    class h_stretch {
2125        const GLfloat hw_w, hw_h;
2126    public:
2127        h_stretch(uint32_t hw_w, uint32_t hw_h)
2128        : hw_w(hw_w), hw_h(hw_h) {
2129        }
2130        void operator()(GLfloat* vtx, float v) {
2131            const GLfloat w = hw_w - (hw_w * v);
2132            const GLfloat h = 1.0f;
2133            const GLfloat x = (hw_w - w) * 0.5f;
2134            const GLfloat y = (hw_h - h) * 0.5f;
2135            vtx[0] = x;         vtx[1] = y;
2136            vtx[2] = x;         vtx[3] = y + h;
2137            vtx[4] = x + w;     vtx[5] = y + h;
2138            vtx[6] = x + w;     vtx[7] = y;
2139        }
2140    };
2141
2142    VSyncWaiter vsync(mEventThread);
2143
2144    // the full animation is 12 frames
2145    int nbFrames = 8;
2146    s_curve_interpolator itr(nbFrames, 7.5f);
2147    s_curve_interpolator itg(nbFrames, 8.0f);
2148    s_curve_interpolator itb(nbFrames, 8.5f);
2149
2150    h_stretch hverts(hw_w, hw_h);
2151    glDisable(GL_BLEND);
2152    glDisable(GL_TEXTURE_2D);
2153    glColorMask(1,1,1,1);
2154    for (int i=nbFrames-1 ; i>=0 ; i--) {
2155        const float v = itg(i);
2156        hverts(vtx, v);
2157
2158        // wait for vsync
2159        vsync.wait();
2160
2161        glClear(GL_COLOR_BUFFER_BIT);
2162        glColor4f(1-v, 1-v, 1-v, 1);
2163        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
2164        hw.flip(screenBounds);
2165    }
2166
2167    nbFrames = 4;
2168    v_stretch vverts(hw_w, hw_h);
2169    glEnable(GL_BLEND);
2170    glBlendFunc(GL_ONE, GL_ONE);
2171    for (int i=nbFrames-1 ; i>=0 ; i--) {
2172        float x, y, w, h;
2173        const float vr = itr(i);
2174        const float vg = itg(i);
2175        const float vb = itb(i);
2176
2177        // wait for vsync
2178        vsync.wait();
2179
2180        // clear screen
2181        glColorMask(1,1,1,1);
2182        glClear(GL_COLOR_BUFFER_BIT);
2183        glEnable(GL_TEXTURE_2D);
2184
2185        // draw the red plane
2186        vverts(vtx, vr);
2187        glColorMask(1,0,0,1);
2188        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
2189
2190        // draw the green plane
2191        vverts(vtx, vg);
2192        glColorMask(0,1,0,1);
2193        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
2194
2195        // draw the blue plane
2196        vverts(vtx, vb);
2197        glColorMask(0,0,1,1);
2198        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
2199
2200        hw.flip(screenBounds);
2201    }
2202
2203    glColorMask(1,1,1,1);
2204    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
2205    glDeleteTextures(1, &tname);
2206    glDisable(GL_TEXTURE_2D);
2207    glDisable(GL_BLEND);
2208
2209    return NO_ERROR;
2210}
2211
2212// ---------------------------------------------------------------------------
2213
2214status_t SurfaceFlinger::turnElectronBeamOffImplLocked(int32_t mode)
2215{
2216    ATRACE_CALL();
2217
2218    DisplayHardware& hw(graphicPlane(0).editDisplayHardware());
2219    if (!hw.canDraw()) {
2220        // we're already off
2221        return NO_ERROR;
2222    }
2223
2224    // turn off hwc while we're doing the animation
2225    hw.getHwComposer().disable();
2226    // and make sure to turn it back on (if needed) next time we compose
2227    invalidateHwcGeometry();
2228
2229    if (mode & ISurfaceComposer::eElectronBeamAnimationOff) {
2230        electronBeamOffAnimationImplLocked();
2231    }
2232
2233    // always clear the whole screen at the end of the animation
2234    glClearColor(0,0,0,1);
2235    glClear(GL_COLOR_BUFFER_BIT);
2236    hw.flip( Region(hw.bounds()) );
2237
2238    return NO_ERROR;
2239}
2240
2241status_t SurfaceFlinger::turnElectronBeamOff(int32_t mode)
2242{
2243    class MessageTurnElectronBeamOff : public MessageBase {
2244        SurfaceFlinger* flinger;
2245        int32_t mode;
2246        status_t result;
2247    public:
2248        MessageTurnElectronBeamOff(SurfaceFlinger* flinger, int32_t mode)
2249            : flinger(flinger), mode(mode), result(PERMISSION_DENIED) {
2250        }
2251        status_t getResult() const {
2252            return result;
2253        }
2254        virtual bool handler() {
2255            Mutex::Autolock _l(flinger->mStateLock);
2256            result = flinger->turnElectronBeamOffImplLocked(mode);
2257            return true;
2258        }
2259    };
2260
2261    sp<MessageBase> msg = new MessageTurnElectronBeamOff(this, mode);
2262    status_t res = postMessageSync(msg);
2263    if (res == NO_ERROR) {
2264        res = static_cast<MessageTurnElectronBeamOff*>( msg.get() )->getResult();
2265
2266        // work-around: when the power-manager calls us we activate the
2267        // animation. eventually, the "on" animation will be called
2268        // by the power-manager itself
2269        mElectronBeamAnimationMode = mode;
2270    }
2271    return res;
2272}
2273
2274// ---------------------------------------------------------------------------
2275
2276status_t SurfaceFlinger::turnElectronBeamOnImplLocked(int32_t mode)
2277{
2278    DisplayHardware& hw(graphicPlane(0).editDisplayHardware());
2279    if (hw.canDraw()) {
2280        // we're already on
2281        return NO_ERROR;
2282    }
2283    if (mode & ISurfaceComposer::eElectronBeamAnimationOn) {
2284        electronBeamOnAnimationImplLocked();
2285    }
2286
2287    // make sure to redraw the whole screen when the animation is done
2288    mDirtyRegion.set(hw.bounds());
2289    signalTransaction();
2290
2291    return NO_ERROR;
2292}
2293
2294status_t SurfaceFlinger::turnElectronBeamOn(int32_t mode)
2295{
2296    class MessageTurnElectronBeamOn : public MessageBase {
2297        SurfaceFlinger* flinger;
2298        int32_t mode;
2299        status_t result;
2300    public:
2301        MessageTurnElectronBeamOn(SurfaceFlinger* flinger, int32_t mode)
2302            : flinger(flinger), mode(mode), result(PERMISSION_DENIED) {
2303        }
2304        status_t getResult() const {
2305            return result;
2306        }
2307        virtual bool handler() {
2308            Mutex::Autolock _l(flinger->mStateLock);
2309            result = flinger->turnElectronBeamOnImplLocked(mode);
2310            return true;
2311        }
2312    };
2313
2314    postMessageAsync( new MessageTurnElectronBeamOn(this, mode) );
2315    return NO_ERROR;
2316}
2317
2318// ---------------------------------------------------------------------------
2319
2320status_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy,
2321        sp<IMemoryHeap>* heap,
2322        uint32_t* w, uint32_t* h, PixelFormat* f,
2323        uint32_t sw, uint32_t sh,
2324        uint32_t minLayerZ, uint32_t maxLayerZ)
2325{
2326    ATRACE_CALL();
2327
2328    status_t result = PERMISSION_DENIED;
2329
2330    // only one display supported for now
2331    if (CC_UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
2332        return BAD_VALUE;
2333
2334    if (!GLExtensions::getInstance().haveFramebufferObject())
2335        return INVALID_OPERATION;
2336
2337    // get screen geometry
2338    const DisplayHardware& hw(graphicPlane(dpy).displayHardware());
2339    const uint32_t hw_w = hw.getWidth();
2340    const uint32_t hw_h = hw.getHeight();
2341
2342    if ((sw > hw_w) || (sh > hw_h))
2343        return BAD_VALUE;
2344
2345    sw = (!sw) ? hw_w : sw;
2346    sh = (!sh) ? hw_h : sh;
2347    const size_t size = sw * sh * 4;
2348
2349    //ALOGD("screenshot: sw=%d, sh=%d, minZ=%d, maxZ=%d",
2350    //        sw, sh, minLayerZ, maxLayerZ);
2351
2352    // make sure to clear all GL error flags
2353    while ( glGetError() != GL_NO_ERROR ) ;
2354
2355    // create a FBO
2356    GLuint name, tname;
2357    glGenRenderbuffersOES(1, &tname);
2358    glBindRenderbufferOES(GL_RENDERBUFFER_OES, tname);
2359    glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA8_OES, sw, sh);
2360
2361    glGenFramebuffersOES(1, &name);
2362    glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
2363    glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES,
2364            GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, tname);
2365
2366    GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
2367
2368    if (status == GL_FRAMEBUFFER_COMPLETE_OES) {
2369
2370        // invert everything, b/c glReadPixel() below will invert the FB
2371        glViewport(0, 0, sw, sh);
2372        glMatrixMode(GL_PROJECTION);
2373        glPushMatrix();
2374        glLoadIdentity();
2375        glOrthof(0, hw_w, hw_h, 0, 0, 1);
2376        glMatrixMode(GL_MODELVIEW);
2377
2378        // redraw the screen entirely...
2379        glClearColor(0,0,0,1);
2380        glClear(GL_COLOR_BUFFER_BIT);
2381
2382        const LayerVector& layers(mDrawingState.layersSortedByZ);
2383        const size_t count = layers.size();
2384        for (size_t i=0 ; i<count ; ++i) {
2385            const sp<LayerBase>& layer(layers[i]);
2386            const uint32_t flags = layer->drawingState().flags;
2387            if (!(flags & ISurfaceComposer::eLayerHidden)) {
2388                const uint32_t z = layer->drawingState().z;
2389                if (z >= minLayerZ && z <= maxLayerZ) {
2390                    layer->drawForSreenShot();
2391                }
2392            }
2393        }
2394
2395        // check for errors and return screen capture
2396        if (glGetError() != GL_NO_ERROR) {
2397            // error while rendering
2398            result = INVALID_OPERATION;
2399        } else {
2400            // allocate shared memory large enough to hold the
2401            // screen capture
2402            sp<MemoryHeapBase> base(
2403                    new MemoryHeapBase(size, 0, "screen-capture") );
2404            void* const ptr = base->getBase();
2405            if (ptr) {
2406                // capture the screen with glReadPixels()
2407                ScopedTrace _t(ATRACE_TAG, "glReadPixels");
2408                glReadPixels(0, 0, sw, sh, GL_RGBA, GL_UNSIGNED_BYTE, ptr);
2409                if (glGetError() == GL_NO_ERROR) {
2410                    *heap = base;
2411                    *w = sw;
2412                    *h = sh;
2413                    *f = PIXEL_FORMAT_RGBA_8888;
2414                    result = NO_ERROR;
2415                }
2416            } else {
2417                result = NO_MEMORY;
2418            }
2419        }
2420        glViewport(0, 0, hw_w, hw_h);
2421        glMatrixMode(GL_PROJECTION);
2422        glPopMatrix();
2423        glMatrixMode(GL_MODELVIEW);
2424    } else {
2425        result = BAD_VALUE;
2426    }
2427
2428    // release FBO resources
2429    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
2430    glDeleteRenderbuffersOES(1, &tname);
2431    glDeleteFramebuffersOES(1, &name);
2432
2433    hw.compositionComplete();
2434
2435    // ALOGD("screenshot: result = %s", result<0 ? strerror(result) : "OK");
2436
2437    return result;
2438}
2439
2440
2441status_t SurfaceFlinger::captureScreen(DisplayID dpy,
2442        sp<IMemoryHeap>* heap,
2443        uint32_t* width, uint32_t* height, PixelFormat* format,
2444        uint32_t sw, uint32_t sh,
2445        uint32_t minLayerZ, uint32_t maxLayerZ)
2446{
2447    // only one display supported for now
2448    if (CC_UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
2449        return BAD_VALUE;
2450
2451    if (!GLExtensions::getInstance().haveFramebufferObject())
2452        return INVALID_OPERATION;
2453
2454    class MessageCaptureScreen : public MessageBase {
2455        SurfaceFlinger* flinger;
2456        DisplayID dpy;
2457        sp<IMemoryHeap>* heap;
2458        uint32_t* w;
2459        uint32_t* h;
2460        PixelFormat* f;
2461        uint32_t sw;
2462        uint32_t sh;
2463        uint32_t minLayerZ;
2464        uint32_t maxLayerZ;
2465        status_t result;
2466    public:
2467        MessageCaptureScreen(SurfaceFlinger* flinger, DisplayID dpy,
2468                sp<IMemoryHeap>* heap, uint32_t* w, uint32_t* h, PixelFormat* f,
2469                uint32_t sw, uint32_t sh,
2470                uint32_t minLayerZ, uint32_t maxLayerZ)
2471            : flinger(flinger), dpy(dpy),
2472              heap(heap), w(w), h(h), f(f), sw(sw), sh(sh),
2473              minLayerZ(minLayerZ), maxLayerZ(maxLayerZ),
2474              result(PERMISSION_DENIED)
2475        {
2476        }
2477        status_t getResult() const {
2478            return result;
2479        }
2480        virtual bool handler() {
2481            Mutex::Autolock _l(flinger->mStateLock);
2482
2483            // if we have secure windows, never allow the screen capture
2484            if (flinger->mSecureFrameBuffer)
2485                return true;
2486
2487            result = flinger->captureScreenImplLocked(dpy,
2488                    heap, w, h, f, sw, sh, minLayerZ, maxLayerZ);
2489
2490            return true;
2491        }
2492    };
2493
2494    sp<MessageBase> msg = new MessageCaptureScreen(this,
2495            dpy, heap, width, height, format, sw, sh, minLayerZ, maxLayerZ);
2496    status_t res = postMessageSync(msg);
2497    if (res == NO_ERROR) {
2498        res = static_cast<MessageCaptureScreen*>( msg.get() )->getResult();
2499    }
2500    return res;
2501}
2502
2503// ---------------------------------------------------------------------------
2504
2505sp<Layer> SurfaceFlinger::getLayer(const sp<ISurface>& sur) const
2506{
2507    sp<Layer> result;
2508    Mutex::Autolock _l(mStateLock);
2509    result = mLayerMap.valueFor( sur->asBinder() ).promote();
2510    return result;
2511}
2512
2513// ---------------------------------------------------------------------------
2514
2515GraphicBufferAlloc::GraphicBufferAlloc() {}
2516
2517GraphicBufferAlloc::~GraphicBufferAlloc() {}
2518
2519sp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h,
2520        PixelFormat format, uint32_t usage, status_t* error) {
2521    sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(w, h, format, usage));
2522    status_t err = graphicBuffer->initCheck();
2523    *error = err;
2524    if (err != 0 || graphicBuffer->handle == 0) {
2525        if (err == NO_MEMORY) {
2526            GraphicBuffer::dumpAllocationsToSystemLog();
2527        }
2528        ALOGE("GraphicBufferAlloc::createGraphicBuffer(w=%d, h=%d) "
2529             "failed (%s), handle=%p",
2530                w, h, strerror(-err), graphicBuffer->handle);
2531        return 0;
2532    }
2533    return graphicBuffer;
2534}
2535
2536// ---------------------------------------------------------------------------
2537
2538GraphicPlane::GraphicPlane()
2539    : mHw(0)
2540{
2541}
2542
2543GraphicPlane::~GraphicPlane() {
2544    delete mHw;
2545}
2546
2547bool GraphicPlane::initialized() const {
2548    return mHw ? true : false;
2549}
2550
2551int GraphicPlane::getWidth() const {
2552    return mWidth;
2553}
2554
2555int GraphicPlane::getHeight() const {
2556    return mHeight;
2557}
2558
2559void GraphicPlane::setDisplayHardware(DisplayHardware *hw)
2560{
2561    mHw = hw;
2562
2563    // initialize the display orientation transform.
2564    // it's a constant that should come from the display driver.
2565    int displayOrientation = ISurfaceComposer::eOrientationDefault;
2566    char property[PROPERTY_VALUE_MAX];
2567    if (property_get("ro.sf.hwrotation", property, NULL) > 0) {
2568        //displayOrientation
2569        switch (atoi(property)) {
2570        case 90:
2571            displayOrientation = ISurfaceComposer::eOrientation90;
2572            break;
2573        case 270:
2574            displayOrientation = ISurfaceComposer::eOrientation270;
2575            break;
2576        }
2577    }
2578
2579    const float w = hw->getWidth();
2580    const float h = hw->getHeight();
2581    GraphicPlane::orientationToTransfrom(displayOrientation, w, h,
2582            &mDisplayTransform);
2583    if (displayOrientation & ISurfaceComposer::eOrientationSwapMask) {
2584        mDisplayWidth = h;
2585        mDisplayHeight = w;
2586    } else {
2587        mDisplayWidth = w;
2588        mDisplayHeight = h;
2589    }
2590
2591    setOrientation(ISurfaceComposer::eOrientationDefault);
2592}
2593
2594status_t GraphicPlane::orientationToTransfrom(
2595        int orientation, int w, int h, Transform* tr)
2596{
2597    uint32_t flags = 0;
2598    switch (orientation) {
2599    case ISurfaceComposer::eOrientationDefault:
2600        flags = Transform::ROT_0;
2601        break;
2602    case ISurfaceComposer::eOrientation90:
2603        flags = Transform::ROT_90;
2604        break;
2605    case ISurfaceComposer::eOrientation180:
2606        flags = Transform::ROT_180;
2607        break;
2608    case ISurfaceComposer::eOrientation270:
2609        flags = Transform::ROT_270;
2610        break;
2611    default:
2612        return BAD_VALUE;
2613    }
2614    tr->set(flags, w, h);
2615    return NO_ERROR;
2616}
2617
2618status_t GraphicPlane::setOrientation(int orientation)
2619{
2620    // If the rotation can be handled in hardware, this is where
2621    // the magic should happen.
2622
2623    const DisplayHardware& hw(displayHardware());
2624    const float w = mDisplayWidth;
2625    const float h = mDisplayHeight;
2626    mWidth = int(w);
2627    mHeight = int(h);
2628
2629    Transform orientationTransform;
2630    GraphicPlane::orientationToTransfrom(orientation, w, h,
2631            &orientationTransform);
2632    if (orientation & ISurfaceComposer::eOrientationSwapMask) {
2633        mWidth = int(h);
2634        mHeight = int(w);
2635    }
2636
2637    mOrientation = orientation;
2638    mGlobalTransform = mDisplayTransform * orientationTransform;
2639    return NO_ERROR;
2640}
2641
2642const DisplayHardware& GraphicPlane::displayHardware() const {
2643    return *mHw;
2644}
2645
2646DisplayHardware& GraphicPlane::editDisplayHardware() {
2647    return *mHw;
2648}
2649
2650const Transform& GraphicPlane::transform() const {
2651    return mGlobalTransform;
2652}
2653
2654EGLDisplay GraphicPlane::getEGLDisplay() const {
2655    return mHw->getEGLDisplay();
2656}
2657
2658// ---------------------------------------------------------------------------
2659
2660}; // namespace android
2661