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