SurfaceFlinger.cpp revision 1604f777d11c40daae8ec91d8ea75625996bfbac
1edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/*
2edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
3edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
4edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * you may not use this file except in compliance with the License.
6edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * You may obtain a copy of the License at
7edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
8edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
10edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * See the License for the specific language governing permissions and
14edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * limitations under the License.
15edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */
16edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
171c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#define ATRACE_TAG ATRACE_TAG_GRAPHICS
181c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
19edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdint.h>
20921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <sys/types.h>
21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <errno.h>
22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <math.h>
2363f165fd6b86d04be94d4023e845e98560504a96Keun young Park#include <dlfcn.h>
24921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
25921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <EGL/egl.h>
26921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <GLES/gl.h>
27edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
28edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/log.h>
29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/properties.h>
30edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
31c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IPCThreadState.h>
32c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IServiceManager.h>
337303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian#include <binder/MemoryHeapBase.h>
3499b49840d309727678b77403d6cc9f920111623fMathias Agopian#include <binder/PermissionCache.h>
357303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
36c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian#include <ui/DisplayInfo.h>
37c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian
38921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <gui/BitTube.h>
391a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <gui/BufferQueue.h>
401a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <gui/IDisplayEventConnection.h>
41921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <gui/SurfaceTextureClient.h>
42921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
43921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <ui/GraphicBufferAllocator.h>
44921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <ui/PixelFormat.h>
45d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
46cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian#include <utils/misc.h>
47edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String8.h>
48edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String16.h>
49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/StopWatch.h>
501c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#include <utils/Trace.h>
51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
52921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <private/android_filesystem_config.h>
53edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h"
5590ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include "DdmConnection.h"
560f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian#include "DisplayDevice.h"
57db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian#include "Client.h"
58d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian#include "EventThread.h"
591f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian#include "GLExtensions.h"
60edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h"
61edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerDim.h"
62118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian#include "LayerScreenshot.h"
63edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h"
64edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
65a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#include "DisplayHardware/FramebufferSurface.h"
66f33e4b6f13bc3ee2d2a4e1abd1ada171c70d3492Mathias Agopian#include "DisplayHardware/GraphicBufferAlloc.h"
67a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian#include "DisplayHardware/HWComposer.h"
68edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
69a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
70bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian#define EGL_VERSION_HW_ANDROID  0x3143
71bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DISPLAY_COUNT       1
73edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
74edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
75edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
76edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
7799b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sHardwareTest("android.permission.HARDWARE_TEST");
7899b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER");
7999b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER");
8099b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sDump("android.permission.DUMP");
8199b49840d309727678b77403d6cc9f920111623fMathias Agopian
8299b49840d309727678b77403d6cc9f920111623fMathias Agopian// ---------------------------------------------------------------------------
8399b49840d309727678b77403d6cc9f920111623fMathias Agopian
84edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::SurfaceFlinger()
85edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    :   BnSurfaceComposer(), Thread(false),
86edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mTransactionFlags(0),
8728378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        mTransationPending(false),
88076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved(false),
8952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        mRepaintEverything(0),
90edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mBootTime(systemTime()),
91edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mVisibleRegionsDirty(false),
92a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        mHwWorkListDirty(false),
93edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDebugRegion(0),
948afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian        mDebugDDMS(0),
9573d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian        mDebugDisableHWC(0),
96a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian        mDebugDisableTransformHint(0),
979795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInSwapBuffers(0),
989795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastSwapBufferTime(0),
999795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInTransaction(0),
1009795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastTransactionTime(0),
1015f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        mBootFinished(false)
102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
103a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI("SurfaceFlinger is starting");
104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // debugging stuff...
106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char value[PROPERTY_VALUE_MAX];
1078afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    property_get("debug.sf.showupdates", value, "0");
109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDebugRegion = atoi(value);
1108afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
1118afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    property_get("debug.sf.ddms", value, "0");
1128afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    mDebugDDMS = atoi(value);
1138afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    if (mDebugDDMS) {
11463f165fd6b86d04be94d4023e845e98560504a96Keun young Park        if (!startDdmConnection()) {
11563f165fd6b86d04be94d4023e845e98560504a96Keun young Park            // start failed, and DDMS debugging not enabled
11663f165fd6b86d04be94d4023e845e98560504a96Keun young Park            mDebugDDMS = 0;
11763f165fd6b86d04be94d4023e845e98560504a96Keun young Park        }
1188afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    }
119c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    ALOGI_IF(mDebugRegion, "showupdates enabled");
120c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    ALOGI_IF(mDebugDDMS, "DDMS debugging enabled");
121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
12399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::onFirstRef()
12499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
12599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.init(this);
12699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
12799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY);
12899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
12999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // Wait for the main thread to be done with its initialization
13099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mReadyToRunBarrier.wait();
13199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
13299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
13399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::~SurfaceFlinger()
135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
136a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
137a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
138a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglTerminate(display);
139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
14199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::binderDied(const wp<IBinder>& who)
14299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
14399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // the window manager died on us. prepare its eulogy.
14499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
14513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    // restore initial conditions (default device unblank, etc)
14613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    initializeDisplays();
14799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
14899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // restart the boot-animation
149a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    startBootAnim();
15099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
15199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
1527e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopiansp<ISurfaceComposerClient> SurfaceFlinger::createConnection()
153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
15496f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<ISurfaceComposerClient> bclient;
15596f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<Client> client(new Client(this));
15696f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = client->initCheck();
15796f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR) {
15896f0819f81293076e652792794a961543e6750d7Mathias Agopian        bclient = client;
159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return bclient;
161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1638dfa92fef9759a881e96ee58d59875d35023aab9Andy McFaddensp<IBinder> SurfaceFlinger::createDisplay(const String8& displayName)
164e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{
165e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    class DisplayToken : public BBinder {
166e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        sp<SurfaceFlinger> flinger;
167e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        virtual ~DisplayToken() {
168e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             // no more references, this display must be terminated
169e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             Mutex::Autolock _l(flinger->mStateLock);
170e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             flinger->mCurrentState.displays.removeItem(this);
171e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             flinger->setTransactionFlags(eDisplayTransactionNeeded);
172e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian         }
173e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian     public:
174e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        DisplayToken(const sp<SurfaceFlinger>& flinger)
175e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            : flinger(flinger) {
176e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
177e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    };
178e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
179e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    sp<BBinder> token = new DisplayToken(this);
180e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
181e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    Mutex::Autolock _l(mStateLock);
1823ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    DisplayDeviceState info(DisplayDevice::DISPLAY_VIRTUAL);
1838dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden    info.displayName = displayName;
184e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    mCurrentState.displays.add(token, info);
185e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
186e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return token;
187e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
188e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
189e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopiansp<IBinder> SurfaceFlinger::getBuiltInDisplay(int32_t id) {
1903ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    if (uint32_t(id) >= DisplayDevice::NUM_DISPLAY_TYPES) {
191e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        ALOGE("getDefaultDisplay: id=%d is not a valid default display id", id);
192e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        return NULL;
193e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
194e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return mDefaultDisplays[id];
195e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
196e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
1979a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc()
1989a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis{
1999a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc());
2009a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    return gba;
2019a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis}
202b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
203edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::bootFinished()
204edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
205edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t now = systemTime();
206edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t duration = now - mBootTime;
207a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
2083330b203039dea366d4981db1408a460134b2d2cMathias Agopian    mBootFinished = true;
2091f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
2101f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // wait patiently for the window manager death
2111f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    const String16 name("window");
2121f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    sp<IBinder> window(defaultServiceManager()->getService(name));
2131f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    if (window != 0) {
214921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        window->linkToDeath(static_cast<IBinder::DeathRecipient*>(this));
2151f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    }
2161f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
2171f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // stop boot animation
218a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // formerly we would just kill the process, but we now ask it to exit so it
219a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // can choose where to stop the animation.
220a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("service.bootanim.exit", "1");
221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
223921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianvoid SurfaceFlinger::deleteTextureAsync(GLuint texture) {
224921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    class MessageDestroyGLTexture : public MessageBase {
225921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        GLuint texture;
226921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    public:
227921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        MessageDestroyGLTexture(GLuint texture)
228921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian            : texture(texture) {
229921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        }
230921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        virtual bool handler() {
231921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian            glDeleteTextures(1, &texture);
232921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian            return true;
233921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        }
234921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    };
235921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    postMessageAsync(new MessageDestroyGLTexture(texture));
236921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
237921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
238a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianstatus_t SurfaceFlinger::selectConfigForPixelFormat(
239a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        EGLDisplay dpy,
240a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        EGLint const* attrs,
241a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        PixelFormat format,
242a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        EGLConfig* outConfig)
243a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian{
244a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLConfig config = NULL;
245a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLint numConfigs = -1, n=0;
246a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglGetConfigs(dpy, NULL, 0, &numConfigs);
247a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLConfig* const configs = new EGLConfig[numConfigs];
248a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglChooseConfig(dpy, attrs, configs, numConfigs, &n);
249cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian
250a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    for (int i=0 ; i<n ; i++) {
251a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        EGLint nativeVisualId = 0;
252a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        eglGetConfigAttrib(dpy, configs[i], EGL_NATIVE_VISUAL_ID, &nativeVisualId);
253a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        if (nativeVisualId>0 && format == nativeVisualId) {
254a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            *outConfig = configs[i];
255a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            delete [] configs;
256a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            return NO_ERROR;
257a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        }
258a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    }
259a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    delete [] configs;
260a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    return NAME_NOT_FOUND;
261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
263a49126087b4494f4ef50873f3a3f6727265f6621Mathias AgopianEGLConfig SurfaceFlinger::selectEGLConfig(EGLDisplay display, EGLint nativeVisualId) {
264a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // select our EGLConfig. It must support EGL_RECORDABLE_ANDROID if
265a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // it is to be used with WIFI displays
266a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLConfig config;
267a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLint dummy;
268a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    status_t err;
269da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
270a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLint attribs[] = {
271a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            EGL_SURFACE_TYPE,           EGL_WINDOW_BIT,
272f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall            // The rest of the attributes must be in this order and at the end
273f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall            // of the list; we rely on that for fallback searches below.
274cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian            EGL_RED_SIZE,               8,
275cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian            EGL_GREEN_SIZE,             8,
276cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian            EGL_BLUE_SIZE,              8,
277a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            EGL_RECORDABLE_ANDROID,     EGL_TRUE,
278a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            EGL_NONE
279a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    };
280a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    err = selectConfigForPixelFormat(display, attribs, nativeVisualId, &config);
281f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall    if (!err)
282f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall        goto success;
283f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall
284f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall    // maybe we failed because of EGL_RECORDABLE_ANDROID
285f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall    ALOGW("no suitable EGLConfig found, trying without EGL_RECORDABLE_ANDROID");
286f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall    attribs[NELEM(attribs) - 3] = EGL_NONE;
287f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall    err = selectConfigForPixelFormat(display, attribs, nativeVisualId, &config);
288f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall    if (!err)
289f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall        goto success;
290f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall
291f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall    // allow less than 24-bit color; the non-gpu-accelerated emulator only
292f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall    // supports 16-bit color
293f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall    ALOGW("no suitable EGLConfig found, trying with 16-bit color allowed");
294f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall    attribs[NELEM(attribs) - 9] = EGL_NONE;
295f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall    err = selectConfigForPixelFormat(display, attribs, nativeVisualId, &config);
296f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall    if (!err)
297f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall        goto success;
298f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall
299f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall    // this EGL is too lame for Android
300f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall    ALOGE("no suitable EGLConfig found, giving up");
301f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall
302f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall    return 0;
303f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall
304f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hallsuccess:
305f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall    if (eglGetConfigAttrib(display, config, EGL_CONFIG_CAVEAT, &dummy))
306a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        ALOGW_IF(dummy == EGL_SLOW_CONFIG, "EGL_SLOW_CONFIG selected!");
307a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    return config;
308a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
310a49126087b4494f4ef50873f3a3f6727265f6621Mathias AgopianEGLContext SurfaceFlinger::createGLContext(EGLDisplay display, EGLConfig config) {
311a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // Also create our EGLContext
312a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLint contextAttributes[] = {
313a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#ifdef EGL_IMG_context_priority
314a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#ifdef HAS_CONTEXT_PRIORITY
315a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#warning "using EGL_IMG_context_priority"
316a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_HIGH_IMG,
317a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#endif
318a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#endif
319a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            EGL_NONE, EGL_NONE
320a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    };
321a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLContext ctxt = eglCreateContext(display, config, NULL, contextAttributes);
322a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGE_IF(ctxt==EGL_NO_CONTEXT, "EGLContext creation failed");
323a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    return ctxt;
324a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
325edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
326cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopianvoid SurfaceFlinger::initializeGL(EGLDisplay display) {
327a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    GLExtensions& extensions(GLExtensions::getInstance());
328a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    extensions.initWithGLStrings(
329a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            glGetString(GL_VENDOR),
330a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            glGetString(GL_RENDERER),
331a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            glGetString(GL_VERSION),
332a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            glGetString(GL_EXTENSIONS),
333a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            eglQueryString(display, EGL_VENDOR),
334a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            eglQueryString(display, EGL_VERSION),
335a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            eglQueryString(display, EGL_EXTENSIONS));
3368b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
337a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
338a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    glGetIntegerv(GL_MAX_VIEWPORT_DIMS, mMaxViewportDims);
3397303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
340edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
3418b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber    glPixelStorei(GL_PACK_ALIGNMENT, 4);
342edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glEnableClientState(GL_VERTEX_ARRAY);
343edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glShadeModel(GL_FLAT);
344edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_DITHER);
345edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_CULL_FACE);
346edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
347a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    struct pack565 {
348a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        inline uint16_t operator() (int r, int g, int b) const {
349a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            return (r<<11)|(g<<5)|b;
350a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        }
351a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    } pack565;
352a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
3539575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    const uint16_t protTexData[] = { pack565(0x03, 0x03, 0x03) };
3549575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glGenTextures(1, &mProtectedTexName);
3559575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glBindTexture(GL_TEXTURE_2D, mProtectedTexName);
3569575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3579575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3589575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
3599575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
3609575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0,
3619575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis            GL_RGB, GL_UNSIGNED_SHORT_5_6_5, protTexData);
362edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
363a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // print some debugging info
364a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLint r,g,b,a;
365a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglGetConfigAttrib(display, mEGLConfig, EGL_RED_SIZE,   &r);
366a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglGetConfigAttrib(display, mEGLConfig, EGL_GREEN_SIZE, &g);
367a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglGetConfigAttrib(display, mEGLConfig, EGL_BLUE_SIZE,  &b);
368a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglGetConfigAttrib(display, mEGLConfig, EGL_ALPHA_SIZE, &a);
369a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("EGL informations:");
370a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("vendor    : %s", extensions.getEglVendor());
371a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("version   : %s", extensions.getEglVersion());
372a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("extensions: %s", extensions.getEglExtension());
373a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("Client API: %s", eglQueryString(display, EGL_CLIENT_APIS)?:"Not Supported");
374a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("EGLSurface: %d-%d-%d-%d, config=%p", r, g, b, a, mEGLConfig);
375a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("OpenGL ES informations:");
376a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("vendor    : %s", extensions.getVendor());
377a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("renderer  : %s", extensions.getRenderer());
378a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("version   : %s", extensions.getVersion());
379a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("extensions: %s", extensions.getExtension());
380a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("GL_MAX_TEXTURE_SIZE = %d", mMaxTextureSize);
381a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("GL_MAX_VIEWPORT_DIMS = %d x %d", mMaxViewportDims[0], mMaxViewportDims[1]);
382a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
383a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
384a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianstatus_t SurfaceFlinger::readyToRun()
385a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian{
386a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI(  "SurfaceFlinger's main thread ready to run. "
387a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            "Initializing graphics H/W...");
388a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
389b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden    // initialize EGL for the default display
39034a09ba1efd706323a15633da5044b352988eb5fJesse Hall    mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
39134a09ba1efd706323a15633da5044b352988eb5fJesse Hall    eglInitialize(mEGLDisplay, NULL, NULL);
392a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
393b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden    // Initialize the H/W composer object.  There may or may not be an
394b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden    // actual hardware composer underneath.
395b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden    mHwc = new HWComposer(this,
396b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden            *static_cast<HWComposer::EventHandler *>(this));
397b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden
398a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // initialize the config and context
399cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian    EGLint format = mHwc->getVisualID();
40034a09ba1efd706323a15633da5044b352988eb5fJesse Hall    mEGLConfig  = selectEGLConfig(mEGLDisplay, format);
40134a09ba1efd706323a15633da5044b352988eb5fJesse Hall    mEGLContext = createGLContext(mEGLDisplay, mEGLConfig);
402a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
403da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian    LOG_ALWAYS_FATAL_IF(mEGLContext == EGL_NO_CONTEXT,
404da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian            "couldn't create EGLContext");
405da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
406cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian    // initialize our non-virtual displays
4073ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    for (size_t i=0 ; i<DisplayDevice::NUM_DISPLAY_TYPES ; i++) {
408e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        mDefaultDisplays[i] = new BBinder();
4093ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian        mCurrentState.displays.add(mDefaultDisplays[i],
410cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                DisplayDeviceState(DisplayDevice::DisplayType(i)));
411e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
412cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian
413cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian    // The main display is a bit special and always exists
414cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian    //
415cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian    // if we didn't add it here, it would be added automatically during the
416cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian    // first transaction, however this would also create some difficulties:
417cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian    //
418cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian    // - there would be a race where a client could call getDisplayInfo(),
419cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian    //   for instance before the DisplayDevice is created.
420cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian    //
421cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian    // - we need a GL context current in a few places, when initializing
422cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian    //   OpenGL ES (see below), or creating a layer,
423cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian    //   or when a texture is (asynchronously) destroyed, and for that
424cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian    //   we need a valid surface, so it's conveniant to use the main display
425cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian    //   for that.
426cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian
427cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian    sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc);
428cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian    sp<SurfaceTextureClient> stc = new SurfaceTextureClient(
429cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                static_cast< sp<ISurfaceTexture> >(fbs->getBufferQueue()));
430e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    sp<DisplayDevice> hw = new DisplayDevice(this,
4313ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian            DisplayDevice::DISPLAY_PRIMARY,
4323ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian            mDefaultDisplays[DisplayDevice::DISPLAY_PRIMARY],
433cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian            stc, fbs, mEGLConfig);
4343ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    mDisplays.add(mDefaultDisplays[DisplayDevice::DISPLAY_PRIMARY], hw);
435a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
436cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian
437a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    //  initialize OpenGL ES
438cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian    DisplayDevice::makeCurrent(mEGLDisplay, hw, mEGLContext);
439cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian    initializeGL(mEGLDisplay);
440d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
441028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian    // start the EventThread
442028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian    mEventThread = new EventThread(this);
443028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian    mEventQueue.setEventThread(mEventThread);
444028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian
44592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    // initialize our drawing state
44692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    mDrawingState = mCurrentState;
4478630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
448cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian
449a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // We're now ready to accept clients...
450d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian    mReadyToRunBarrier.open();
451d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
45213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    // set initial conditions (e.g. unblank default device)
45313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    initializeDisplays();
45413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
455a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    // start boot animation
456a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    startBootAnim();
4578b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
458edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
459edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
460edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
4613ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopianint32_t SurfaceFlinger::allocateHwcDisplayId(DisplayDevice::DisplayType type) {
4623ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    return (uint32_t(type) < DisplayDevice::NUM_DISPLAY_TYPES) ?
4633ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian            type : mHwc->allocateDisplayId();
4643ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian}
4653ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian
466a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopianvoid SurfaceFlinger::startBootAnim() {
467a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // start boot animation
468a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("service.bootanim.exit", "0");
469a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("ctl.start", "bootanim");
470a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian}
471a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian
472a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianuint32_t SurfaceFlinger::getMaxTextureSize() const {
473a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    return mMaxTextureSize;
474a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
475a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
476a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianuint32_t SurfaceFlinger::getMaxViewportDims() const {
477a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    return mMaxViewportDims[0] < mMaxViewportDims[1] ?
478a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            mMaxViewportDims[0] : mMaxViewportDims[1];
479a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
480a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
481edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
482d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
483582270d69db94286a248bd829f1ae6f910d45124Jamie Gennisbool SurfaceFlinger::authenticateSurfaceTexture(
484582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis        const sp<ISurfaceTexture>& surfaceTexture) const {
485134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    Mutex::Autolock _l(mStateLock);
486582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis    sp<IBinder> surfaceTextureBinder(surfaceTexture->asBinder());
487134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
488134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // Check the visible layer list for the ISurface
489134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
490134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    size_t count = currentLayers.size();
491134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    for (size_t i=0 ; i<count ; i++) {
492134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        const sp<LayerBase>& layer(currentLayers[i]);
493134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        sp<LayerBaseClient> lbc(layer->getLayerBaseClient());
494582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis        if (lbc != NULL) {
495582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder();
496582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            if (lbcBinder == surfaceTextureBinder) {
497582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis                return true;
498582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            }
499134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        }
500134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    }
501134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
502134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // Check the layers in the purgatory.  This check is here so that if a
503582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis    // SurfaceTexture gets destroyed before all the clients are done using it,
504582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis    // the error will not be reported as "surface XYZ is not authenticated", but
505134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // will instead fail later on when the client tries to use the surface,
506134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // which should be reported as "surface XYZ returned an -ENODEV".  The
507134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // purgatorized layers are no less authentic than the visible ones, so this
508134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // should not cause any harm.
509134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    size_t purgatorySize =  mLayerPurgatory.size();
510134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    for (size_t i=0 ; i<purgatorySize ; i++) {
511134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
512134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        sp<LayerBaseClient> lbc(layer->getLayerBaseClient());
513582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis        if (lbc != NULL) {
514582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder();
515582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            if (lbcBinder == surfaceTextureBinder) {
516582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis                return true;
517582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            }
518134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        }
519134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    }
520134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
521134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    return false;
522134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis}
523134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
5249d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brownstatus_t SurfaceFlinger::getDisplayInfo(const sp<IBinder>& display, DisplayInfo* info) {
5251604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian    int32_t type = BAD_VALUE;
5261604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian    for (int i=0 ; i<DisplayDevice::NUM_DISPLAY_TYPES ; i++) {
5271604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        if (display == mDefaultDisplays[i]) {
5281604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian            type = i;
5291604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian            break;
5301604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        }
5311604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian    }
5321604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian
5331604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian    if (type < 0) {
5341604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        return type;
535c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian    }
5368b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian
5378b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    const HWComposer& hwc(getHwComposer());
5381604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian    float xdpi = hwc.getDpiX(type);
5391604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian    float ydpi = hwc.getDpiY(type);
5408b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian
5418b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    // TODO: Not sure if display density should handled by SF any longer
5428b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    class Density {
5438b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        static int getDensityFromProperty(char const* propName) {
5448b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            char property[PROPERTY_VALUE_MAX];
5458b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            int density = 0;
5468b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            if (property_get(propName, property, NULL) > 0) {
5478b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian                density = atoi(property);
5488b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            }
5498b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            return density;
5508b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        }
5518b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    public:
5528b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        static int getEmuDensity() {
5538b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            return getDensityFromProperty("qemu.sf.lcd_density"); }
5548b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        static int getBuildDensity()  {
5558b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            return getDensityFromProperty("ro.sf.lcd_density"); }
5568b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    };
5571604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian
5581604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian    if (type == DisplayDevice::DISPLAY_PRIMARY) {
5591604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        // The density of the device is provided by a build property
5601604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        float density = Density::getBuildDensity() / 160.0f;
5611604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        if (density == 0) {
5621604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian            // the build doesn't provide a density -- this is wrong!
5631604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian            // use xdpi instead
5641604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian            ALOGE("ro.sf.lcd_density must be defined as a build property");
5651604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian            density = xdpi / 160.0f;
5661604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        }
5671604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        if (Density::getEmuDensity()) {
5681604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian            // if "qemu.sf.lcd_density" is specified, it overrides everything
5691604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian            xdpi = ydpi = density = Density::getEmuDensity();
5701604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian            density /= 160.0f;
5711604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        }
5721604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        info->density = density;
5731604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian
5741604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        // TODO: this needs to go away (currently needed only by webkit)
5751604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        sp<const DisplayDevice> hw(getDefaultDisplayDevice());
5761604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        info->orientation = hw->getOrientation();
5771604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        getPixelFormatInfo(hw->getFormat(), &info->pixelFormatInfo);
5781604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian    } else {
5791604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        // TODO: where should this value come from?
5801604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        static const int TV_DENSITY = 213;
5811604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        info->density = TV_DENSITY / 160.0f;
5821604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        info->orientation = 0;
5838b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    }
5848b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian
5851604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian    info->w = hwc.getWidth(type);
5861604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian    info->h = hwc.getHeight(type);
5878b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    info->xdpi = xdpi;
5888b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    info->ydpi = ydpi;
5891604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian    info->fps = float(1e9 / hwc.getRefreshPeriod(type));
590888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian    return NO_ERROR;
591c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian}
592c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian
593d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian// ----------------------------------------------------------------------------
594d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
595d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopiansp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection() {
5968aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian    return mEventThread->createEventConnection();
597bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian}
598bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
5999d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brownvoid SurfaceFlinger::connectDisplay(const sp<ISurfaceTexture>& surface) {
6003094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
6015f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    sp<IBinder> token;
6023094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    { // scope for the lock
6033094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        Mutex::Autolock _l(mStateLock);
6045f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        token = mExtDisplayToken;
6053094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    }
6063094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
6075f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    if (token == 0) {
6088dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden        token = createDisplay(String8("Display from connectDisplay"));
6093094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    }
6103094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
6115f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    { // scope for the lock
6125f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        Mutex::Autolock _l(mStateLock);
6135f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        if (surface == 0) {
6145f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian            // release our current display. we're guarantee to have
6155f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian            // a reference to it (token), while we hold the lock
6165f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian            mExtDisplayToken = 0;
6175f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        } else {
6185f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian            mExtDisplayToken = token;
6195f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        }
6205f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian
6215f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        DisplayDeviceState& info(mCurrentState.displays.editValueFor(token));
6225f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        info.surface = surface;
6235f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        setTransactionFlags(eDisplayTransactionNeeded);
6245f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    }
6253094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian}
6263094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
627edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
62899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
62999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::waitForEvent() {
63099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.waitMessage();
63199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
63299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
63399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalTransaction() {
63499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.invalidate();
63599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
63699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
63799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalLayerUpdate() {
63899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.invalidate();
63999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
64099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
64199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalRefresh() {
64299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.refresh();
64399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
64499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
64599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg,
64699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        nsecs_t reltime, uint32_t flags) {
64799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return mEventQueue.postMessage(msg, reltime);
64899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
64999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
65099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,
65199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        nsecs_t reltime, uint32_t flags) {
65299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    status_t res = mEventQueue.postMessage(msg, reltime);
65399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    if (res == NO_ERROR) {
65499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        msg->wait();
65599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    }
65699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return res;
65799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
658edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
6594fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianbool SurfaceFlinger::threadLoop() {
660edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    waitForEvent();
66199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return true;
66299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
663edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
6643ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopianvoid SurfaceFlinger::onVSyncReceived(int type, nsecs_t timestamp) {
66543601a2dc320a271ff8c3765ff61414a07221635Andy McFadden    if (mEventThread == NULL) {
66643601a2dc320a271ff8c3765ff61414a07221635Andy McFadden        // This is a temporary workaround for b/7145521.  A non-null pointer
66743601a2dc320a271ff8c3765ff61414a07221635Andy McFadden        // does not mean EventThread has finished initializing, so this
66843601a2dc320a271ff8c3765ff61414a07221635Andy McFadden        // is not a correct fix.
66943601a2dc320a271ff8c3765ff61414a07221635Andy McFadden        ALOGW("WARNING: EventThread not started, ignoring vsync");
67043601a2dc320a271ff8c3765ff61414a07221635Andy McFadden        return;
67143601a2dc320a271ff8c3765ff61414a07221635Andy McFadden    }
6723ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    if (uint32_t(type) < DisplayDevice::NUM_DISPLAY_TYPES) {
6733ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian        // we should only receive DisplayDevice::DisplayType from the vsync callback
6743ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian        const wp<IBinder>& token(mDefaultDisplays[type]);
6753ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian        mEventThread->onVSyncReceived(token, timestamp);
6763ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    }
6778630320433bd15aca239522e54e711ef6372ab07Mathias Agopian}
6788630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
6798630320433bd15aca239522e54e711ef6372ab07Mathias Agopianvoid SurfaceFlinger::eventControl(int event, int enabled) {
6808630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    getHwComposer().eventControl(event, enabled);
6818630320433bd15aca239522e54e711ef6372ab07Mathias Agopian}
6828630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
6834fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::onMessageReceived(int32_t what) {
6841c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
68599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    switch (what) {
6864fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    case MessageQueue::INVALIDATE:
6874fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        handleMessageTransaction();
6884fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        handleMessageInvalidate();
6894fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        signalRefresh();
6904fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        break;
6914fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    case MessageQueue::REFRESH:
6924fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        handleMessageRefresh();
6934fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        break;
6944fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
6954fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
696edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
6974fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageTransaction() {
698e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    uint32_t transactionFlags = peekTransactionFlags(eTransactionMask);
6994fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    if (transactionFlags) {
70087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        handleTransaction(transactionFlags);
7014fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
7024fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
703edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
7044fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageInvalidate() {
705cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    ATRACE_CALL();
70687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    handlePageFlip();
7074fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
7083a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian
7094fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageRefresh() {
710cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    ATRACE_CALL();
711cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    preComposition();
712cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    rebuildLayerStacks();
713cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    setUpHWComposer();
714cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    doDebugFlashRegions();
715cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    doComposition();
716cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    postComposition();
717cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
718cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
719cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doDebugFlashRegions()
720cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{
721cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    // is debugging enabled
722cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (CC_LIKELY(!mDebugRegion))
723cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        return;
724cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
725cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    const bool repaintEverything = mRepaintEverything;
726cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
727cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
728cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        if (hw->canDraw()) {
729cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            // transform the dirty region into this screen's coordinate space
730cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            const Region dirtyRegion(hw->getDirtyRegion(repaintEverything));
731cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            if (!dirtyRegion.isEmpty()) {
732cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                // redraw the whole screen
733cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                doComposeSurfaces(hw, Region(hw->bounds()));
734cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
735cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                // and draw the dirty region
736cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                glDisable(GL_TEXTURE_EXTERNAL_OES);
737cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                glDisable(GL_TEXTURE_2D);
738cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                glDisable(GL_BLEND);
739cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                glColor4f(1, 0, 1, 1);
740cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                const int32_t height = hw->getHeight();
741cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                Region::const_iterator it = dirtyRegion.begin();
742cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                Region::const_iterator const end = dirtyRegion.end();
743cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                while (it != end) {
744cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                    const Rect& r = *it++;
745cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                    GLfloat vertices[][2] = {
746cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            { r.left,  height - r.top },
747cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            { r.left,  height - r.bottom },
748cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            { r.right, height - r.bottom },
749cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            { r.right, height - r.top }
750cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                    };
751cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                    glVertexPointer(2, GL_FLOAT, 0, vertices);
752cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
753cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                }
754cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                hw->compositionComplete();
755da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                hw->swapBuffers(getHwComposer());
756cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            }
757cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        }
758cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
759cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
760cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    postFramebuffer();
761cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
762cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (mDebugRegion > 1) {
763cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        usleep(mDebugRegion * 1000);
764cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
765cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
766cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
767cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::preComposition()
768cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{
769cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    bool needExtraInvalidate = false;
770cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
771cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    const size_t count = currentLayers.size();
772cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    for (size_t i=0 ; i<count ; i++) {
773cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        if (currentLayers[i]->onPreComposition()) {
774cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            needExtraInvalidate = true;
775cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        }
776cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
777cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (needExtraInvalidate) {
778cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        signalLayerUpdate();
779cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
780cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
781a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
782cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::postComposition()
783cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{
784cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
785cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    const size_t count = currentLayers.size();
786cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    for (size_t i=0 ; i<count ; i++) {
787cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        currentLayers[i]->onPostComposition();
788cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
789cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
790cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
791cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::rebuildLayerStacks() {
792cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    // rebuild the visible layer list per screen
79352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    if (CC_UNLIKELY(mVisibleRegionsDirty)) {
794cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        ATRACE_CALL();
79587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        mVisibleRegionsDirty = false;
79687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        invalidateHwcGeometry();
797ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian
79887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
79992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
800ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian            Region opaqueRegion;
801ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian            Region dirtyRegion;
802ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian            Vector< sp<LayerBase> > layersSortedByZ;
8034297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            const sp<DisplayDevice>& hw(mDisplays[dpy]);
8047e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian            const Transform& tr(hw->getTransform());
8057e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian            const Rect bounds(hw->getBounds());
806ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian            if (hw->canDraw()) {
807ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                SurfaceFlinger::computeVisibleRegions(currentLayers,
808ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                        hw->getLayerStack(), dirtyRegion, opaqueRegion);
8097e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian
810ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                const size_t count = currentLayers.size();
811ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                for (size_t i=0 ; i<count ; i++) {
812ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                    const sp<LayerBase>& layer(currentLayers[i]);
813ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                    const Layer::State& s(layer->drawingState());
814ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                    if (s.layerStack == hw->getLayerStack()) {
815ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                        Region visibleRegion(tr.transform(layer->visibleRegion));
816ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                        visibleRegion.andSelf(bounds);
817ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                        if (!visibleRegion.isEmpty()) {
818ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                            layersSortedByZ.add(layer);
819ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                        }
82087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian                    }
82187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian                }
8223b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian            }
8234297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->setVisibleLayersSortedByZ(layersSortedByZ);
8247e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian            hw->undefinedRegion.set(bounds);
8257e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian            hw->undefinedRegion.subtractSelf(tr.transform(opaqueRegion));
8267e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian            hw->dirtyRegion.orSelf(dirtyRegion);
8273b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        }
8283b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
829cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
8303b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
831cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::setUpHWComposer() {
83252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    HWComposer& hwc(getHwComposer());
83352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    if (hwc.initCheck() == NO_ERROR) {
83452bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        // build the h/w work list
83552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        const bool workListsDirty = mHwWorkListDirty;
83652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        mHwWorkListDirty = false;
83792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
8384297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            sp<const DisplayDevice> hw(mDisplays[dpy]);
839e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian            const int32_t id = hw->getHwcDisplayId();
840e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian            if (id >= 0) {
841e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                const Vector< sp<LayerBase> >& currentLayers(
842cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                    hw->getVisibleLayersSortedByZ());
843e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                const size_t count = currentLayers.size();
844e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                if (hwc.createWorkList(id, count) >= 0) {
845e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                    HWComposer::LayerListIterator cur = hwc.begin(id);
846e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                    const HWComposer::LayerListIterator end = hwc.end(id);
847e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                    for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
848e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                        const sp<LayerBase>& layer(currentLayers[i]);
849e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian
850e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                        if (CC_UNLIKELY(workListsDirty)) {
851e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                            layer->setGeometry(hw, *cur);
852e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                            if (mDebugDisableHWC || mDebugRegion) {
853e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                                cur->setSkip(true);
854e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                            }
8551e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                        }
85652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian
857e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                        /*
858e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                         * update the per-frame h/w composer data for each layer
859e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                         * and build the transparent region of the FB
860e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                         */
861e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                        layer->setPerFrameData(hw, *cur);
862e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                    }
8631e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                }
86452bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            }
86587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        }
86652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        status_t err = hwc.prepare();
86752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
86852bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    }
869cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
87052bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian
871cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doComposition() {
872cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    ATRACE_CALL();
87352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    const bool repaintEverything = android_atomic_and(0, &mRepaintEverything);
87492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
8754297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
876cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        if (hw->canDraw()) {
877cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            // transform the dirty region into this screen's coordinate space
878cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            const Region dirtyRegion(hw->getDirtyRegion(repaintEverything));
879cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            if (!dirtyRegion.isEmpty()) {
88052bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian                // repaint the framebuffer (if needed)
881cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                doDisplayComposition(hw, dirtyRegion);
88252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            }
883cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            hw->dirtyRegion.clear();
884cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            hw->flip(hw->swapRegion);
885cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            hw->swapRegion.clear();
88687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        }
88752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        // inform the h/w that we're done compositing
8884297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        hw->compositionComplete();
8894fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
89052bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    postFramebuffer();
891edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
892edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
893edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer()
894edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
895841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
896b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian
897a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    const nsecs_t now = systemTime();
898a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = now;
899c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall
90052bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    HWComposer& hwc(getHwComposer());
901ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall    if (hwc.initCheck() == NO_ERROR) {
9025f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        // FIXME: EGL spec says:
9035f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        //   "surface must be bound to the calling thread's current context,
9045f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        //    for the current rendering API."
905da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian        DisplayDevice::makeCurrent(mEGLDisplay, getDefaultDisplayDevice(), mEGLContext);
906e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian        hwc.commit();
90752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    }
90852bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian
90992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
9104297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        sp<const DisplayDevice> hw(mDisplays[dpy]);
9114297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const Vector< sp<LayerBase> >& currentLayers(hw->getVisibleLayersSortedByZ());
912da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian        hw->onSwapBuffersCompleted(hwc);
91352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        const size_t count = currentLayers.size();
914e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian        int32_t id = hw->getHwcDisplayId();
915e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian        if (id >=0 && hwc.initCheck() == NO_ERROR) {
9161e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian            HWComposer::LayerListIterator cur = hwc.begin(id);
9171e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian            const HWComposer::LayerListIterator end = hwc.end(id);
91852bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            for (size_t i = 0; cur != end && i < count; ++i, ++cur) {
919d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian                currentLayers[i]->onLayerDisplayed(hw, &*cur);
92052bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            }
921cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        } else {
92252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            for (size_t i = 0; i < count; i++) {
923d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian                currentLayers[i]->onLayerDisplayed(hw, NULL);
92452bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            }
925ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall        }
926e8696a40e09b24b634214684d18526187b316a2fJamie Gennis    }
927e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
928a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mLastSwapBufferTime = systemTime() - now;
929a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = 0;
930edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
931edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
93287baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
933edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
934841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
935841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
936ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    Mutex::Autolock _l(mStateLock);
937ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    const nsecs_t now = systemTime();
938ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = now;
939ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
940ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // Here we're guaranteed that some transaction flags are set
941ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // so we can call handleTransactionLocked() unconditionally.
942ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // We call getTransactionFlags(), which will also clear the flags,
943ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // with mStateLock held to guarantee that mCurrentState won't change
944ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // until the transaction is committed.
945ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
946e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    transactionFlags = getTransactionFlags(eTransactionMask);
94787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    handleTransactionLocked(transactionFlags);
948ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
949ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mLastTransactionTime = systemTime() - now;
950ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = 0;
951ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    invalidateHwcGeometry();
952ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // here the transaction has been committed
9533d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian}
954edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
95587baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
9563d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{
9573d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    const LayerVector& currentLayers(mCurrentState.layersSortedByZ);
958edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t count = currentLayers.size();
959edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
960edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
961edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Traversal of the children
962edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * (perform the transaction for each of them if needed)
963edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
964edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
9653559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    if (transactionFlags & eTraversalNeeded) {
966edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (size_t i=0 ; i<count ; i++) {
967076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            const sp<LayerBase>& layer = currentLayers[i];
968edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
969edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (!trFlags) continue;
970edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
971edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const uint32_t flags = layer->doTransaction(0);
972edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (flags & Layer::eVisibleRegion)
973edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mVisibleRegionsDirty = true;
974edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
975edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
976edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
977edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
9783559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian     * Perform display own transactions if needed
979edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
980edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
981e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    if (transactionFlags & eDisplayTransactionNeeded) {
98292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        // here we take advantage of Vector's copy-on-write semantics to
98392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        // improve performance by skipping the transaction entirely when
98492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        // know that the lists are identical
985e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const KeyedVector<  wp<IBinder>, DisplayDeviceState>& curr(mCurrentState.displays);
986e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const KeyedVector<  wp<IBinder>, DisplayDeviceState>& draw(mDrawingState.displays);
98792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        if (!curr.isIdenticalTo(draw)) {
988edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
98992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            const size_t cc = curr.size();
99093997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                  size_t dc = draw.size();
99192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian
99292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // find the displays that were removed
99392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // (ie: in drawing state but not in current state)
99492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // also handle displays that changed
99592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // (ie: displays that are in both lists)
99692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            for (size_t i=0 ; i<dc ; i++) {
997e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                const ssize_t j = curr.indexOfKey(draw.keyAt(i));
998e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                if (j < 0) {
99992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    // in drawing state but not in current state
10003ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian                    if (!draw[i].isMainDisplay()) {
10013ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian                        mDisplays.removeItem(draw.keyAt(i));
100292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    } else {
100392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                        ALOGW("trying to remove the main display");
100492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    }
100592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                } else {
100692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    // this display is in both lists. see if something changed.
1007e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                    const DisplayDeviceState& state(curr[j]);
10083ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian                    const wp<IBinder>& display(curr.keyAt(j));
1009111b2d89221722d38f5b5b3ba65904ec22421839Mathias Agopian                    if (state.surface->asBinder() != draw[i].surface->asBinder()) {
1010e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        // changing the surface is like destroying and
101193997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // recreating the DisplayDevice, so we just remove it
101293997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // from the drawing state, so that it get re-added
101393997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // below.
101493997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        mDisplays.removeItem(display);
101593997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        mDrawingState.displays.removeItemsAt(i);
101693997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        dc--; i--;
101793997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // at this point we must loop to the next item
101893997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        continue;
101992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    }
102093997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian
102193997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                    const sp<DisplayDevice>& disp(getDisplayDevice(display));
102293997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                    if (disp != NULL) {
102393997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        if (state.layerStack != draw[i].layerStack) {
102493997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                            disp->setLayerStack(state.layerStack);
102593997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        }
102600e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                        if ((state.orientation != draw[i].orientation)
102700e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                                || (state.viewport != draw[i].viewport)
102800e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                                || (state.frame != draw[i].frame))
102900e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                        {
103000e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                            disp->setProjection(state.orientation,
10314fb3999cea652617be5125f8a42c257467bf3c77Jeff Brown                                    state.viewport, state.frame);
103293997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        }
10336905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden
10346905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                        // Walk through all the layers in currentLayers,
10356905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                        // and update their transform hint.
10366905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                        //
10376905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                        // TODO: we could be much more clever about which
10386905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                        // layers we touch and how often we do these updates
10396905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                        // (e.g. only touch the layers associated with this
10406905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                        // display, and only on a rotation).
10416905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                        for (size_t i = 0; i < count; i++) {
10426905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                            const sp<LayerBase>& layerBase = currentLayers[i];
10436905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                            layerBase->updateTransformHint();
10446905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                        }
104592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    }
104692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                }
104792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            }
104892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian
104992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // find displays that were added
105092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // (ie: in current state but not in drawing state)
105192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            for (size_t i=0 ; i<cc ; i++) {
1052e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                if (draw.indexOfKey(curr.keyAt(i)) < 0) {
1053e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                    const DisplayDeviceState& state(curr[i]);
1054cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian
1055cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                    sp<FramebufferSurface> fbs;
1056cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                    sp<SurfaceTextureClient> stc;
1057cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                    if (!state.isVirtualDisplay()) {
1058cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian
1059cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        ALOGE_IF(state.surface!=NULL,
1060cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                                "adding a supported display, but rendering "
1061cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                                "surface is provided (%p), ignoring it",
1062cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                                state.surface.get());
1063cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian
1064cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        // for supported (by hwc) displays we provide our
1065cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        // own rendering surface
1066cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        fbs = new FramebufferSurface(*mHwc);
1067cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        stc = new SurfaceTextureClient(
1068cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                                static_cast< sp<ISurfaceTexture> >(fbs->getBufferQueue()));
1069cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                    } else {
1070cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        if (state.surface != NULL) {
1071cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                            stc = new SurfaceTextureClient(state.surface);
1072cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        }
1073cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                    }
1074cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian
1075cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                    const wp<IBinder>& display(curr.keyAt(i));
1076cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                    if (stc != NULL) {
1077cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        sp<DisplayDevice> hw = new DisplayDevice(this,
1078cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                                state.type, display, stc, fbs, mEGLConfig);
1079cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        hw->setLayerStack(state.layerStack);
1080cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        hw->setProjection(state.orientation,
10814fb3999cea652617be5125f8a42c257467bf3c77Jeff Brown                                state.viewport, state.frame);
10828dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden                        hw->setDisplayName(state.displayName);
1083cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        mDisplays.add(display, hw);
1084cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        if (hw->getDisplayType() < DisplayDevice::NUM_DISPLAY_TYPES) {
1085cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                            // notify the system that this display is now up
1086cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                            // (note onScreenAcquired() is safe to call from
1087cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                            // here because we're in the main thread)
1088cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                            onScreenAcquired(hw);
1089cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        }
109093997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                    }
109192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                }
109292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            }
1093edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
10943559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    }
1095edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
10963559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    /*
10973559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian     * Perform our own transaction if needed
10983559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian     */
1099edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1100cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    const LayerVector& previousLayers(mDrawingState.layersSortedByZ);
1101cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (currentLayers.size() > previousLayers.size()) {
11023559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        // layers have been added
11033559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        mVisibleRegionsDirty = true;
11043559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    }
11053559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian
11063559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    // some layers might have been removed, so
11073559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    // we need to update the regions they're exposing.
11083559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    if (mLayersRemoved) {
11093559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        mLayersRemoved = false;
11103559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        mVisibleRegionsDirty = true;
11113559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        const size_t count = previousLayers.size();
11123559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        for (size_t i=0 ; i<count ; i++) {
11133559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian            const sp<LayerBase>& layer(previousLayers[i]);
11143559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian            if (currentLayers.indexOf(layer) < 0) {
11153559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                // this layer is not visible anymore
11163559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                // TODO: we could traverse the tree from front to back and
11173559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                //       compute the actual visible region
11183559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                // TODO: we could cache the transformed region
11191501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian                const Layer::State& s(layer->drawingState());
11201501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian                Region visibleReg = s.transform.transform(
11211501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian                        Region(Rect(s.active.w, s.active.h)));
11221501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian                invalidateLayerStack(s.layerStack, visibleReg);
11230aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            }
1124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1125edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1126edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1127edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    commitTransaction();
11284fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
11294fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
11304fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::commitTransaction()
11314fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian{
11324fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    if (!mLayersPendingRemoval.isEmpty()) {
11334fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // Notify removed layers now that they can't be drawn from
11344fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        for (size_t i = 0; i < mLayersPendingRemoval.size(); i++) {
11354fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            mLayersPendingRemoval[i]->onRemoved();
11364fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        }
11374fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        mLayersPendingRemoval.clear();
11384fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
11394fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
11404fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mDrawingState = mCurrentState;
11414fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mTransationPending = false;
11424fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mTransactionCV.broadcast();
1143edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1145edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::computeVisibleRegions(
114687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const LayerVector& currentLayers, uint32_t layerStack,
114787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        Region& outDirtyRegion, Region& outOpaqueRegion)
1148edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1149841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
1150841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
1151edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveOpaqueLayers;
1152edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveCoveredLayers;
1153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region dirty;
1154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
115587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    outDirtyRegion.clear();
1156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t i = currentLayers.size();
1158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    while (i--) {
1159076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        const sp<LayerBase>& layer = currentLayers[i];
1160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // start with the whole surface at its current location
1162970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian        const Layer::State& s(layer->drawingState());
1163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
116487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        // only consider the layers on the given later stack
116587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        if (s.layerStack != layerStack)
116687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            continue;
116787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
1168ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
1169ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * opaqueRegion: area of a surface that is fully opaque.
1170ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
1171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region opaqueRegion;
1172ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1173ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
1174ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visibleRegion: area of a surface that is visible on screen
1175ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * and not fully transparent. This is essentially the layer's
1176ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * footprint minus the opaque regions above it.
1177ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * Areas covered by a translucent surface are considered visible.
1178ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
1179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region visibleRegion;
1180ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1181ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
1182ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * coveredRegion: area of a surface that is covered by all
1183ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visible regions above it (which includes the translucent areas).
1184ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
1185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region coveredRegion;
1186ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1187ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1188ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // handle hidden surfaces by setting the visible region to empty
1189da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian        if (CC_LIKELY(layer->isVisible())) {
1190a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            const bool translucent = !layer->isOpaque();
11914fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            Rect bounds(layer->computeBounds());
1192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            visibleRegion.set(bounds);
1193ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            if (!visibleRegion.isEmpty()) {
1194ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // Remove the transparent area from the visible region
1195ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (translucent) {
11964fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    Region transparentRegionScreen;
11974fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    const Transform tr(s.transform);
11984fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    if (tr.transformed()) {
11994fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                        if (tr.preserveRects()) {
12004fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            // transform the transparent region
12014fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            transparentRegionScreen = tr.transform(s.transparentRegion);
12024fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                        } else {
12034fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            // transformation too complex, can't do the
12044fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            // transparent region optimization.
12054fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            transparentRegionScreen.clear();
12064fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                        }
12074fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    } else {
12084fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                        transparentRegionScreen = s.transparentRegion;
12094fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    }
12104fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    visibleRegion.subtractSelf(transparentRegionScreen);
1211ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
1212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1213ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // compute the opaque region
12144fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                const int32_t layerOrientation = s.transform.getOrientation();
1215ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (s.alpha==255 && !translucent &&
1216ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                        ((layerOrientation & Transform::ROT_INVALID) == false)) {
1217ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    // the opaque region is the layer's footprint
1218ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    opaqueRegion = visibleRegion;
1219ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
1220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1223ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Clip the covered region to the visible region
1224ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        coveredRegion = aboveCoveredLayers.intersect(visibleRegion);
1225ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1226ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveCoveredLayers for next (lower) layer
1227ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        aboveCoveredLayers.orSelf(visibleRegion);
1228ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // subtract the opaque region covered by the layers above us
1230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        visibleRegion.subtractSelf(aboveOpaqueLayers);
1231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // compute this layer's dirty region
1233edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (layer->contentDirty) {
1234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // we need to invalidate the whole region
1235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dirty = visibleRegion;
1236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // as well, as the old visible region
12374fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            dirty.orSelf(layer->visibleRegion);
1238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->contentDirty = false;
1239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
1240a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian            /* compute the exposed region:
1241ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   the exposed region consists of two components:
1242ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   1) what's VISIBLE now and was COVERED before
1243ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   2) what's EXPOSED now less what was EXPOSED before
1244ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
1245ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * note that (1) is conservative, we start with the whole
1246ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * visible region but only keep what used to be covered by
1247ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * something -- which mean it may have been exposed.
1248ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
1249ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * (2) handles areas that were not covered by anything but got
1250ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * exposed because of a resize.
1251a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian             */
1252ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region newExposed = visibleRegion - coveredRegion;
12534fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region oldVisibleRegion = layer->visibleRegion;
12544fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region oldCoveredRegion = layer->coveredRegion;
1255ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldExposed = oldVisibleRegion - oldCoveredRegion;
1256ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed);
1257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirty.subtractSelf(aboveOpaqueLayers);
1259edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // accumulate to the screen dirty region
126187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        outDirtyRegion.orSelf(dirty);
1262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1263ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveOpaqueLayers for next (lower) layer
1264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        aboveOpaqueLayers.orSelf(opaqueRegion);
12658b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
1266edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // Store the visible region is screen space
1267edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setVisibleRegion(visibleRegion);
1268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setCoveredRegion(coveredRegion);
1269edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
127187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    outOpaqueRegion = aboveOpaqueLayers;
1272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
127487baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::invalidateLayerStack(uint32_t layerStack,
127587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const Region& dirty) {
127692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
12774297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
12784297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        if (hw->getLayerStack() == layerStack) {
12794297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->dirtyRegion.orSelf(dirty);
128092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        }
128192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    }
128287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian}
128387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
128487baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handlePageFlip()
1285edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
12864fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    Region dirtyRegion;
128799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
12884fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    bool visibleRegions = false;
1289cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
12904fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    const size_t count = currentLayers.size();
12914fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    for (size_t i=0 ; i<count ; i++) {
1292cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
129387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const Region dirty(layer->latchBuffer(visibleRegions));
12941501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian        const Layer::State& s(layer->drawingState());
129587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        invalidateLayerStack(s.layerStack, dirty);
12964fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
12974da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
12983b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    mVisibleRegionsDirty |= visibleRegions;
1299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1301ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopianvoid SurfaceFlinger::invalidateHwcGeometry()
1302ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian{
1303ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian    mHwWorkListDirty = true;
1304ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian}
1305ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian
130699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
1307cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doDisplayComposition(const sp<const DisplayDevice>& hw,
130887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const Region& inDirtyRegion)
1309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
131087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    Region dirtyRegion(inDirtyRegion);
131187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
1312b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // compute the invalid region
13134297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->swapRegion.orSelf(dirtyRegion);
1314edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
13154297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    uint32_t flags = hw->getFlags();
13160f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian    if (flags & DisplayDevice::SWAP_RECTANGLE) {
131729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // we can redraw only what's dirty, but since SWAP_RECTANGLE only
131829d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // takes a rectangle, we must make sure to update that whole
131929d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // rectangle in that case
13204297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        dirtyRegion.set(hw->swapRegion.bounds());
1321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
13220f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian        if (flags & DisplayDevice::PARTIAL_UPDATES) {
132329d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // We need to redraw the rectangle that will be updated
1324df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian            // (pushed to the framebuffer).
132595a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian            // This is needed because PARTIAL_UPDATES only takes one
13260f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian            // rectangle instead of a region (see DisplayDevice::flip())
13274297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            dirtyRegion.set(hw->swapRegion.bounds());
1328edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
132929d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // we need to redraw everything (the whole screen)
13304297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            dirtyRegion.set(hw->bounds());
13314297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->swapRegion = dirtyRegion;
1332edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1334edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1335cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    doComposeSurfaces(hw, dirtyRegion);
1336edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
13379c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    // update the swap region and clear the dirty region
13384297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->swapRegion.orSelf(dirtyRegion);
1339da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
1340da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian    // swap buffers (presentation)
1341da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian    hw->swapBuffers(getHwComposer());
1342edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1343edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1344cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& hw, const Region& dirty)
1345edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
134685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    const int32_t id = hw->getHwcDisplayId();
13478630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    HWComposer& hwc(getHwComposer());
13481e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian    HWComposer::LayerListIterator cur = hwc.begin(id);
13491e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian    const HWComposer::LayerListIterator end = hwc.end(id);
1350a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
135185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    const bool hasGlesComposition = hwc.hasGlesComposition(id) || (cur==end);
135285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    if (hasGlesComposition) {
1353da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian        DisplayDevice::makeCurrent(mEGLDisplay, hw, mEGLContext);
1354a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
135552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        // set the frame buffer
135652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        glMatrixMode(GL_MODELVIEW);
135752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        glLoadIdentity();
1358a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
1359a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        // Never touch the framebuffer if we don't have any framebuffer layers
136085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        const bool hasHwcComposition = hwc.hasHwcComposition(id);
1361e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian        if (hasHwcComposition) {
1362b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // when using overlays, we assume a fully transparent framebuffer
1363b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // NOTE: we could reduce how much we need to clear, for instance
1364b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // remove where there are opaque FB layers. however, on some
1365b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // GPUs doing a "clean slate" glClear might be more efficient.
1366b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // We'll revisit later if needed.
1367b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            glClearColor(0, 0, 0, 0);
1368b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            glClear(GL_COLOR_BUFFER_BIT);
1369b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian        } else {
13704297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            const Region region(hw->undefinedRegion.intersect(dirty));
1371b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // screen is already cleared here
137287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            if (!region.isEmpty()) {
1373b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                // can happen with SurfaceView
137455801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian                drawWormhole(hw, region);
1375b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            }
1376a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        }
137785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    }
13784b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian
137985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    /*
138085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian     * and then, render the layers targeted at the framebuffer
138185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian     */
13824b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian
138385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    const Vector< sp<LayerBase> >& layers(hw->getVisibleLayersSortedByZ());
138485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    const size_t count = layers.size();
138585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    const Transform& tr = hw->getTransform();
138685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    if (cur != end) {
138785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        // we're using h/w composer
138885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        for (size_t i=0 ; i<count && cur!=end ; ++i, ++cur) {
1389a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian            const sp<LayerBase>& layer(layers[i]);
13904fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region clip(dirty.intersect(tr.transform(layer->visibleRegion)));
139185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            if (!clip.isEmpty()) {
139285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                switch (cur->getCompositionType()) {
139385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                    case HWC_OVERLAY: {
139485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                        if ((cur->getHints() & HWC_HINT_CLEAR_FB)
139585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                                && i
139685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                                && layer->isOpaque()
139785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                                && hasGlesComposition) {
1398cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            // never clear the very first layer since we're
1399cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            // guaranteed the FB is already cleared
1400cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            layer->clearWithOpenGL(hw, clip);
1401cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                        }
140285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                        break;
140385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                    }
140485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                    case HWC_FRAMEBUFFER: {
1405cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                        layer->draw(hw, clip);
140685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                        break;
1407a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                    }
1408da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                    case HWC_FRAMEBUFFER_TARGET: {
1409da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                        // this should not happen as the iterator shouldn't
1410da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                        // let us get there.
1411da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                        ALOGW("HWC_FRAMEBUFFER_TARGET found in hwc list (index=%d)", i);
1412da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                        break;
1413da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                    }
1414cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                }
1415a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall            }
141685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            layer->setAcquireFence(hw, *cur);
141785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        }
141885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    } else {
141985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        // we're not using h/w composer
142085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        for (size_t i=0 ; i<count ; ++i) {
142185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            const sp<LayerBase>& layer(layers[i]);
142285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            const Region clip(dirty.intersect(
142385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                    tr.transform(layer->visibleRegion)));
142485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            if (!clip.isEmpty()) {
142585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                layer->draw(hw, clip);
142685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            }
14274b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian        }
14284b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian    }
1429edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1430edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
143155801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopianvoid SurfaceFlinger::drawWormhole(const sp<const DisplayDevice>& hw,
143255801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian        const Region& region) const
1433edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1434f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    glDisable(GL_TEXTURE_EXTERNAL_OES);
1435b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian    glDisable(GL_TEXTURE_2D);
1436f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    glDisable(GL_BLEND);
1437b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian    glColor4f(0,0,0,0);
1438f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian
143955801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian    const int32_t height = hw->getHeight();
1440f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    Region::const_iterator it = region.begin();
1441f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    Region::const_iterator const end = region.end();
1442f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    while (it != end) {
1443f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        const Rect& r = *it++;
144455801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian        GLfloat vertices[][2] = {
144555801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian                { r.left,  height - r.top },
144655801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian                { r.left,  height - r.bottom },
144755801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian                { r.right, height - r.bottom },
144855801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian                { r.right, height - r.top }
144955801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian        };
145055801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian        glVertexPointer(2, GL_FLOAT, 0, vertices);
1451f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1452f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    }
1453edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1454edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
145596f0819f81293076e652792794a961543e6750d7Mathias Agopianssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
145696f0819f81293076e652792794a961543e6750d7Mathias Agopian        const sp<LayerBaseClient>& lbc)
14571b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
145896f0819f81293076e652792794a961543e6750d7Mathias Agopian    // attach this layer to the client
14594f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    size_t name = client->attachLayer(lbc);
14604f113740180b6512b43723c4728f262882dc9b45Mathias Agopian
146196f0819f81293076e652792794a961543e6750d7Mathias Agopian    // add this layer to the current state list
1462921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    Mutex::Autolock _l(mStateLock);
1463921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    mCurrentState.layersSortedByZ.add(lbc);
146496f0819f81293076e652792794a961543e6750d7Mathias Agopian
14654f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    return ssize_t(name);
146696f0819f81293076e652792794a961543e6750d7Mathias Agopian}
146796f0819f81293076e652792794a961543e6750d7Mathias Agopian
146896f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer)
146996f0819f81293076e652792794a961543e6750d7Mathias Agopian{
147096f0819f81293076e652792794a961543e6750d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
147196f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = purgatorizeLayer_l(layer);
147296f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR)
14733559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        setTransactionFlags(eTransactionNeeded);
147496f0819f81293076e652792794a961543e6750d7Mathias Agopian    return err;
1475edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1476edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1477076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase)
1478edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1479edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase);
1480edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (index >= 0) {
1481076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved = true;
1482edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
1483edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
14843d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    return status_t(index);
1485edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1486edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
14879a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase)
14889a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
148976cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    // First add the layer to the purgatory list, which makes sure it won't
149076cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    // go away, then remove it from the main list (through a transaction).
14919a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    ssize_t err = removeLayer_l(layerBase);
149276cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    if (err >= 0) {
149376cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian        mLayerPurgatory.add(layerBase);
149476cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    }
14958c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian
14962f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall    mLayersPendingRemoval.push(layerBase);
14970b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian
14983d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // it's possible that we don't find a layer, because it might
14993d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // have been destroyed already -- this is not technically an error
150096f0819f81293076e652792794a961543e6750d7Mathias Agopian    // from the user because there is a race between Client::destroySurface(),
150196f0819f81293076e652792794a961543e6750d7Mathias Agopian    // ~Client() and ~ISurface().
15029a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err;
15039a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
15049a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
1505dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopianuint32_t SurfaceFlinger::peekTransactionFlags(uint32_t flags)
1506dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian{
1507dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian    return android_atomic_release_load(&mTransactionFlags);
1508dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian}
1509dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian
1510edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags)
1511edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1512edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return android_atomic_and(~flags, &mTransactionFlags) & flags;
1513edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1514edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1515bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags)
1516edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1517edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t old = android_atomic_or(flags, &mTransactionFlags);
1518edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((old & flags)==0) { // wake the server up
151999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        signalTransaction();
1520edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1521edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return old;
1522edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1523edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
15248b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopianvoid SurfaceFlinger::setTransactionState(
15258b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        const Vector<ComposerState>& state,
15268b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        const Vector<DisplayState>& displays,
15278b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        uint32_t flags)
15288b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian{
1529698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
153028378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    uint32_t transactionFlags = 0;
1531e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
1532e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    size_t count = displays.size();
1533e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
1534e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const DisplayState& s(displays[i]);
1535e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        transactionFlags |= setDisplayStateLocked(s);
1536b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis    }
1537b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis
1538e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    count = state.size();
1539698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
1540698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const ComposerState& s(state[i]);
1541698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        sp<Client> client( static_cast<Client *>(s.client.get()) );
154228378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        transactionFlags |= setClientStateLocked(client, s.state);
1543698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    }
1544386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian
154528378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    if (transactionFlags) {
1546386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // this triggers the transaction
154728378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        setTransactionFlags(transactionFlags);
1548698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian
1549386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // if this is a synchronous transaction, wait for it to take effect
1550386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // before returning.
1551386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        if (flags & eSynchronous) {
1552386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            mTransationPending = true;
1553386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        }
1554386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        while (mTransationPending) {
1555386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
1556386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            if (CC_UNLIKELY(err != NO_ERROR)) {
1557386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                // just in case something goes wrong in SF, return to the
1558386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                // called after a few seconds.
155932397c1cd3327905173b36baa6fd1c579bc328ffSteve Block                ALOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!");
1560386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                mTransationPending = false;
1561386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                break;
1562386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            }
1563cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        }
1564edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1565edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1566edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1567e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setDisplayStateLocked(const DisplayState& s)
1568e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{
1569e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    uint32_t flags = 0;
1570e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    DisplayDeviceState& disp(mCurrentState.displays.editValueFor(s.token));
15713ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    if (disp.isValid()) {
1572e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const uint32_t what = s.what;
1573e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & DisplayState::eSurfaceChanged) {
1574e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.surface->asBinder() != s.surface->asBinder()) {
1575e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.surface = s.surface;
1576e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
1577e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1578e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1579e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & DisplayState::eLayerStackChanged) {
1580e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.layerStack != s.layerStack) {
1581e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.layerStack = s.layerStack;
1582e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
1583e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1584e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
158500e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian        if (what & DisplayState::eDisplayProjectionChanged) {
1586e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.orientation != s.orientation) {
1587e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.orientation = s.orientation;
1588e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
1589e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1590e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.frame != s.frame) {
1591e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.frame = s.frame;
1592e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
1593e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1594e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.viewport != s.viewport) {
1595e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.viewport = s.viewport;
1596e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
1597e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1598e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1599e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
1600e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return flags;
1601e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
1602e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
1603e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setClientStateLocked(
1604e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const sp<Client>& client,
1605e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const layer_state_t& s)
1606e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{
1607e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    uint32_t flags = 0;
1608e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    sp<LayerBaseClient> layer(client->getLayerUser(s.surface));
1609e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    if (layer != 0) {
1610e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const uint32_t what = s.what;
1611e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::ePositionChanged) {
1612e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setPosition(s.x, s.y))
1613e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1614e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1615e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eLayerChanged) {
1616e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            // NOTE: index needs to be calculated before we update the state
1617e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
1618e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setLayer(s.z)) {
1619e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.removeAt(idx);
1620e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.add(layer);
1621e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // we need traversal (state changed)
1622e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // AND transaction (list changed)
1623e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTransactionNeeded|eTraversalNeeded;
1624e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1625e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1626e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eSizeChanged) {
1627e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setSize(s.w, s.h)) {
1628e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1629e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1630e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1631e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eAlphaChanged) {
1632e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f)))
1633e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1634e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1635e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eMatrixChanged) {
1636e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setMatrix(s.matrix))
1637e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1638e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1639e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eTransparentRegionChanged) {
1640e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setTransparentRegionHint(s.transparentRegion))
1641e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1642e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1643e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eVisibilityChanged) {
1644e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setFlags(s.flags, s.mask))
1645e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1646e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1647e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eCropChanged) {
1648e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setCrop(s.crop))
1649e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1650e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1651e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eLayerStackChanged) {
1652e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            // NOTE: index needs to be calculated before we update the state
1653e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
1654e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setLayerStack(s.layerStack)) {
1655e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.removeAt(idx);
1656e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.add(layer);
1657e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // we need traversal (state changed)
1658e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // AND transaction (list changed)
1659e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTransactionNeeded|eTraversalNeeded;
1660e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1661e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1662e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
1663e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return flags;
1664e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
1665e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
1666921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopiansp<ISurface> SurfaceFlinger::createLayer(
16670ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        ISurfaceComposerClient::surface_data_t* params,
16680ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const String8& name,
16690ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const sp<Client>& client,
16703ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian       uint32_t w, uint32_t h, PixelFormat format,
1671edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t flags)
1672edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1673076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBaseClient> layer;
1674a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    sp<ISurface> surfaceHandle;
16756e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian
16766e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    if (int32_t(w|h) < 0) {
1677921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        ALOGE("createLayer() failed, w or h is negative (w=%d, h=%d)",
16786e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian                int(w), int(h));
16796e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian        return surfaceHandle;
16806e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    }
16818b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
1682921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    //ALOGD("createLayer for (%d x %d), name=%s", w, h, name.string());
16833165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian    switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {
16843165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        case ISurfaceComposerClient::eFXSurfaceNormal:
16853ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian            layer = createNormalLayer(client, w, h, flags, format);
1686edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
16873165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        case ISurfaceComposerClient::eFXSurfaceBlur:
16883165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        case ISurfaceComposerClient::eFXSurfaceDim:
16893ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian            layer = createDimLayer(client, w, h, flags);
1690edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
16913165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        case ISurfaceComposerClient::eFXSurfaceScreenshot:
16923ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian            layer = createScreenshotLayer(client, w, h, flags);
1693118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian            break;
1694edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1695edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1696076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (layer != 0) {
169796f0819f81293076e652792794a961543e6750d7Mathias Agopian        layer->initStates(w, h, flags);
1698285dbde2e0cd0057be070ded3be8f5f453147edcMathias Agopian        layer->setName(name);
169996f0819f81293076e652792794a961543e6750d7Mathias Agopian        ssize_t token = addClientLayer(client, layer);
1700edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        surfaceHandle = layer->getSurface();
17018b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber        if (surfaceHandle != 0) {
170296f0819f81293076e652792794a961543e6750d7Mathias Agopian            params->token = token;
1703a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            params->identity = layer->getIdentity();
17041c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        }
170596f0819f81293076e652792794a961543e6750d7Mathias Agopian        setTransactionFlags(eTransactionNeeded);
1706edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1707edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1708edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return surfaceHandle;
1709edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1710edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1711921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopiansp<Layer> SurfaceFlinger::createNormalLayer(
17123ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian        const sp<Client>& client,
171396f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags,
17141c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        PixelFormat& format)
1715edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1716edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize the surfaces
171792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    switch (format) {
1718edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSPARENT:
1719edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSLUCENT:
1720edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        format = PIXEL_FORMAT_RGBA_8888;
1721edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1722edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_OPAQUE:
1723a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888
1724a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian        format = PIXEL_FORMAT_RGB_565;
1725a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#else
17268f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian        format = PIXEL_FORMAT_RGBX_8888;
1727a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif
1728edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1729edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1730edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1731a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888
1732a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian    if (format == PIXEL_FORMAT_RGBX_8888)
1733a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian        format = PIXEL_FORMAT_RGBA_8888;
1734a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif
1735a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian
17363ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    sp<Layer> layer = new Layer(this, client);
1737f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian    status_t err = layer->setBuffers(w, h, format, flags);
173899ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten    if (CC_LIKELY(err != NO_ERROR)) {
1739921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        ALOGE("createNormalLayer() failed (%s)", strerror(-err));
1740076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        layer.clear();
1741edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1742edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1743edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1744edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1745921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopiansp<LayerDim> SurfaceFlinger::createDimLayer(
17463ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian        const sp<Client>& client,
174796f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags)
1748edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
17493ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    sp<LayerDim> layer = new LayerDim(this, client);
1750118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    return layer;
1751118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
1752118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
1753921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopiansp<LayerScreenshot> SurfaceFlinger::createScreenshotLayer(
17543ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian        const sp<Client>& client,
1755118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags)
1756118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{
17573ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    sp<LayerScreenshot> layer = new LayerScreenshot(this, client);
1758edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1759edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1760edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1761921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianstatus_t SurfaceFlinger::onLayerRemoved(const sp<Client>& client, SurfaceID sid)
17629a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
17639a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    /*
17649a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     * called by the window manager, when a surface should be marked for
17659a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     * destruction.
17668b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber     *
17670aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * The surface is removed from the current and drawing lists, but placed
17680aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * in the purgatory queue, so it's not destroyed right-away (we need
17690aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * to wait for all client's references to go away first).
17709a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     */
17719a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
177248d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    status_t err = NAME_NOT_FOUND;
17730aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian    Mutex::Autolock _l(mStateLock);
177496f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<LayerBaseClient> layer = client->getLayerUser(sid);
1775b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam
177648d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    if (layer != 0) {
177748d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        err = purgatorizeLayer_l(layer);
177848d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        if (err == NO_ERROR) {
177913233e067b8f71adc3a0ade5f442265e1f27084bMathias Agopian            setTransactionFlags(eTransactionNeeded);
178048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        }
17819a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    }
17829a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return err;
17839a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
17849a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
1785921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianstatus_t SurfaceFlinger::onLayerDestroyed(const wp<LayerBaseClient>& layer)
1786edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1787759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian    // called by ~ISurface() when all references are gone
1788ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    status_t err = NO_ERROR;
1789ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    sp<LayerBaseClient> l(layer.promote());
1790ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    if (l != NULL) {
1791ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        Mutex::Autolock _l(mStateLock);
1792ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        err = removeLayer_l(l);
1793ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        if (err == NAME_NOT_FOUND) {
1794ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // The surface wasn't in the current list, which means it was
1795ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // removed already, which means it is in the purgatory,
1796ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // and need to be removed from there.
1797ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            ssize_t idx = mLayerPurgatory.remove(l);
1798e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block            ALOGE_IF(idx < 0,
1799ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian                    "layer=%p is not in the purgatory list", l.get());
1800f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        }
1801e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE_IF(err<0 && err != NAME_NOT_FOUND,
1802ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian                "error removing layer=%p (%s)", l.get(), strerror(-err));
1803ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    }
1804ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    return err;
1805edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1806edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1807b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// ---------------------------------------------------------------------------
1808b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
180913a082e160c2d1d8006b93a555a57035213d568bAndy McFaddenvoid SurfaceFlinger::onInitializeDisplays() {
181013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    // reset screen orientation
181113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    Vector<ComposerState> state;
181213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    Vector<DisplayState> displays;
181313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    DisplayState d;
181400e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian    d.what = DisplayState::eDisplayProjectionChanged;
18153ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    d.token = mDefaultDisplays[DisplayDevice::DISPLAY_PRIMARY];
181613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    d.orientation = DisplayState::eOrientationDefault;
18174c05dd175ee3bd5119eecf368742b6510a8cfa6cJeff Brown    d.frame.makeInvalid();
18184c05dd175ee3bd5119eecf368742b6510a8cfa6cJeff Brown    d.viewport.makeInvalid();
181913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    displays.add(d);
182013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    setTransactionState(state, displays, 0);
1821cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian    onScreenAcquired(getDefaultDisplayDevice());
182213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden}
182313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
182413a082e160c2d1d8006b93a555a57035213d568bAndy McFaddenvoid SurfaceFlinger::initializeDisplays() {
182513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    class MessageScreenInitialized : public MessageBase {
182613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden        SurfaceFlinger* flinger;
182713a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    public:
182813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden        MessageScreenInitialized(SurfaceFlinger* flinger) : flinger(flinger) { }
182913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden        virtual bool handler() {
183013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden            flinger->onInitializeDisplays();
183113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden            return true;
183213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden        }
183313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    };
183413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    sp<MessageBase> msg = new MessageScreenInitialized(this);
183513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    postMessageAsync(msg);  // we may be called from main thread, use async message
183613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden}
183713a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
183813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
1839cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopianvoid SurfaceFlinger::onScreenAcquired(const sp<const DisplayDevice>& hw) {
18408e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross    ALOGD("Screen about to return, flinger = %p", this);
18418630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    getHwComposer().acquire();
18424297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->acquireScreen();
1843cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian    if (hw->getDisplayType() == DisplayDevice::DISPLAY_PRIMARY) {
1844cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian        // FIXME: eventthread only knows about the main display right now
1845cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian        mEventThread->onScreenAcquired();
1846cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian    }
184720128300e0cb7f459a60cfbcddb48190ce6545edMathias Agopian    mVisibleRegionsDirty = true;
184820128300e0cb7f459a60cfbcddb48190ce6545edMathias Agopian    repaintEverything();
1849edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1850edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1851cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopianvoid SurfaceFlinger::onScreenReleased(const sp<const DisplayDevice>& hw) {
18528e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross    ALOGD("About to give-up screen, flinger = %p", this);
18534297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    if (hw->isScreenAcquired()) {
1854cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian        if (hw->getDisplayType() == DisplayDevice::DISPLAY_PRIMARY) {
1855cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian            // FIXME: eventthread only knows about the main display right now
1856cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian            mEventThread->onScreenReleased();
1857cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian        }
18584297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        hw->releaseScreen();
18598630320433bd15aca239522e54e711ef6372ab07Mathias Agopian        getHwComposer().release();
1860ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian        mVisibleRegionsDirty = true;
1861b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        // from this point on, SF will stop drawing
1862b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    }
1863b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian}
1864b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
18658e533069e5721e55cb9768e140e16546c3a4a8b6Colin Crossvoid SurfaceFlinger::unblank() {
1866b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    class MessageScreenAcquired : public MessageBase {
1867b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        SurfaceFlinger* flinger;
1868b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    public:
1869b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        MessageScreenAcquired(SurfaceFlinger* flinger) : flinger(flinger) { }
1870b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        virtual bool handler() {
1871cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian            // FIXME: should this be per-display?
1872cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian            flinger->onScreenAcquired(flinger->getDefaultDisplayDevice());
1873b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            return true;
1874b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        }
1875b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    };
1876b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    sp<MessageBase> msg = new MessageScreenAcquired(this);
1877b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    postMessageSync(msg);
1878edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1879edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
18808e533069e5721e55cb9768e140e16546c3a4a8b6Colin Crossvoid SurfaceFlinger::blank() {
1881b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    class MessageScreenReleased : public MessageBase {
1882b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        SurfaceFlinger* flinger;
1883b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    public:
1884b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        MessageScreenReleased(SurfaceFlinger* flinger) : flinger(flinger) { }
1885b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        virtual bool handler() {
1886cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian            // FIXME: should this be per-display?
1887cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian            flinger->onScreenReleased(flinger->getDefaultDisplayDevice());
1888b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            return true;
1889b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        }
1890b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    };
1891b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    sp<MessageBase> msg = new MessageScreenReleased(this);
1892b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    postMessageSync(msg);
1893b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian}
1894b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
1895b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// ---------------------------------------------------------------------------
1896b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
1897edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
1898edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
18991d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling    const size_t SIZE = 4096;
1900edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char buffer[SIZE];
1901edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    String8 result;
190299b49840d309727678b77403d6cc9f920111623fMathias Agopian
190399b49840d309727678b77403d6cc9f920111623fMathias Agopian    if (!PermissionCache::checkCallingPermission(sDump)) {
1904edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        snprintf(buffer, SIZE, "Permission Denial: "
1905edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                "can't dump SurfaceFlinger from pid=%d, uid=%d\n",
1906edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                IPCThreadState::self()->getCallingPid(),
1907edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                IPCThreadState::self()->getCallingUid());
1908edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        result.append(buffer);
1909edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
19109795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // Try to get the main lock, but don't insist if we can't
19119795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // (this would indicate SF is stuck, but we want to be able to
19129795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // print something in dumpsys).
19139795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        int retry = 3;
19149795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        while (mStateLock.tryLock()<0 && --retry>=0) {
19159795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            usleep(1000000);
19169795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
19179795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const bool locked(retry >= 0);
19189795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (!locked) {
19198b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber            snprintf(buffer, SIZE,
19209795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "SurfaceFlinger appears to be unresponsive, "
19219795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "dumping anyways (no locks held)\n");
19229795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            result.append(buffer);
19239795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
19249795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
192582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        bool dumpAll = true;
192682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        size_t index = 0;
192725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        size_t numArgs = args.size();
192825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        if (numArgs) {
192925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
193025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--list"))) {
193125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                index++;
193225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                listLayersLocked(args, index, result, buffer, SIZE);
193335aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
193425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            }
193525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
193625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
193725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--latency"))) {
193882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                index++;
193982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                dumpStatsLocked(args, index, result, buffer, SIZE);
194035aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
194182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            }
194225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
194325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
194425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--latency-clear"))) {
194525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                index++;
194625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                clearStatsLocked(args, index, result, buffer, SIZE);
194735aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
194825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            }
1949edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
19501b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
195182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (dumpAll) {
195282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            dumpAllLocked(result, buffer, SIZE);
195382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
195448b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
195582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (locked) {
195682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mStateLock.unlock();
195748b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        }
195882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
195982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    write(fd, result.string(), result.size());
196082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    return NO_ERROR;
196182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
196248b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
196325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::listLayersLocked(const Vector<String16>& args, size_t& index,
196425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        String8& result, char* buffer, size_t SIZE) const
196525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
196625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
196725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const size_t count = currentLayers.size();
196825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
196925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
197025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        snprintf(buffer, SIZE, "%s\n", layer->getName().string());
197125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        result.append(buffer);
197225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
197325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
197425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
197582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index,
197682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        String8& result, char* buffer, size_t SIZE) const
197782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
197882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    String8 name;
197982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    if (index < args.size()) {
198082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        name = String8(args[index]);
198182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        index++;
198282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
198348b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
198482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
198582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const size_t count = currentLayers.size();
198682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    for (size_t i=0 ; i<count ; i++) {
198782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
198882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (name.isEmpty()) {
198982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            snprintf(buffer, SIZE, "%s\n", layer->getName().string());
199082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            result.append(buffer);
199182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
199282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (name.isEmpty() || (name == layer->getName())) {
199382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            layer->dumpStats(result, buffer, SIZE);
199482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
199582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
199682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
1997ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian
199825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& index,
199925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        String8& result, char* buffer, size_t SIZE) const
200025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
200125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    String8 name;
200225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    if (index < args.size()) {
200325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        name = String8(args[index]);
200425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        index++;
200525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
200625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
200725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
200825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const size_t count = currentLayers.size();
200925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
201025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
201125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        if (name.isEmpty() || (name == layer->getName())) {
201225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            layer->clearStats();
201325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        }
201425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
201525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
201625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
201782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpAllLocked(
201882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        String8& result, char* buffer, size_t SIZE) const
201982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
202082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    // figure out if we're stuck somewhere
202182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t now = systemTime();
202282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t inSwapBuffers(mDebugInSwapBuffers);
202382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t inTransaction(mDebugInTransaction);
202482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0;
202582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0;
2026bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
202782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
202882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump the visible layer list
202982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
203082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
203182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const size_t count = currentLayers.size();
203282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "Visible layers (count = %d)\n", count);
203382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
203482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    for (size_t i=0 ; i<count ; i++) {
203582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
203682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        layer->dump(result, buffer, SIZE);
203782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
2038bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
203982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
204082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump the layers in the purgatory
204182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
2042ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian
204382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const size_t purgatorySize = mLayerPurgatory.size();
204482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "Purgatory state (%d entries)\n", purgatorySize);
204582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
204682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    for (size_t i=0 ; i<purgatorySize ; i++) {
204782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
204882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        layer->shortDump(result, buffer, SIZE);
204982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
20501b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
205182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
20525f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian     * Dump Display state
20535f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian     */
20545f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian
20558dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden    snprintf(buffer, SIZE, "Displays (%d entries)\n", mDisplays.size());
20568dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden    result.append(buffer);
20575f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
20585f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        const sp<const DisplayDevice>& hw(mDisplays[dpy]);
20591d12d8a8e61163b35cf42c51c558a67138014e82Mathias Agopian        hw->dump(result, buffer, SIZE);
20605f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    }
20615f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian
20625f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    /*
206382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump SurfaceFlinger global state
206482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
20651b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
206682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "SurfaceFlinger global state:\n");
206782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
20681b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
2069888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian    HWComposer& hwc(getHwComposer());
20704297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    sp<const DisplayDevice> hw(getDefaultDisplayDevice());
207182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const GLExtensions& extensions(GLExtensions::getInstance());
207282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "GLES: %s, %s, %s\n",
207382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            extensions.getVendor(),
207482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            extensions.getRenderer(),
207582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            extensions.getVersion());
207682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
2077d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
207882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "EGL : %s\n",
2079d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian            eglQueryString(mEGLDisplay, EGL_VERSION_HW_ANDROID));
208082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
208173d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian
208282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "EXTS: %s\n", extensions.getExtension());
208382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
20849795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
20854297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->undefinedRegion.dump(result, "undefinedRegion");
208682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE,
208782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  orientation=%d, canDraw=%d\n",
20884297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->getOrientation(), hw->canDraw());
208982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
209082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE,
209182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  last eglSwapBuffers() time: %f us\n"
209282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  last transaction time     : %f us\n"
2093c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian            "  transaction-flags         : %08x\n"
209482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  refresh-rate              : %f fps\n"
209582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  x-dpi                     : %f\n"
20968b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            "  y-dpi                     : %f\n",
209782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mLastSwapBufferTime/1000.0,
209882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mLastTransactionTime/1000.0,
2099c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian            mTransactionFlags,
2100b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden            1e9 / hwc.getRefreshPeriod(HWC_DISPLAY_PRIMARY),
2101b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden            hwc.getDpiX(HWC_DISPLAY_PRIMARY),
2102b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden            hwc.getDpiY(HWC_DISPLAY_PRIMARY));
210382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
210482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
210582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "  eglSwapBuffers time: %f us\n",
210682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            inSwapBuffersDuration/1000.0);
210782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
210882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
210982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "  transaction time: %f us\n",
211082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            inTransactionDuration/1000.0);
211182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
211282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
211382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
211482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * VSYNC state
211582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
211682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    mEventThread->dump(result, buffer, SIZE);
211782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
211882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
211982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump HWComposer state
212082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
212182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "h/w composer state:\n");
212282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
212382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "  h/w composer %s and %s\n",
212482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            hwc.initCheck()==NO_ERROR ? "present" : "not present",
212582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                    (mDebugDisableHWC || mDebugRegion) ? "disabled" : "enabled");
212682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
21274297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hwc.dump(result, buffer, SIZE, hw->getVisibleLayersSortedByZ());
212882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
212982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
213082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump gralloc state
213182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
213282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
213382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    alloc.dump(result);
2134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
213663f165fd6b86d04be94d4023e845e98560504a96Keun young Parkbool SurfaceFlinger::startDdmConnection()
213763f165fd6b86d04be94d4023e845e98560504a96Keun young Park{
213863f165fd6b86d04be94d4023e845e98560504a96Keun young Park    void* libddmconnection_dso =
213963f165fd6b86d04be94d4023e845e98560504a96Keun young Park            dlopen("libsurfaceflinger_ddmconnection.so", RTLD_NOW);
214063f165fd6b86d04be94d4023e845e98560504a96Keun young Park    if (!libddmconnection_dso) {
214163f165fd6b86d04be94d4023e845e98560504a96Keun young Park        return false;
214263f165fd6b86d04be94d4023e845e98560504a96Keun young Park    }
214363f165fd6b86d04be94d4023e845e98560504a96Keun young Park    void (*DdmConnection_start)(const char* name);
214463f165fd6b86d04be94d4023e845e98560504a96Keun young Park    DdmConnection_start =
214563f165fd6b86d04be94d4023e845e98560504a96Keun young Park            (typeof DdmConnection_start)dlsym(libddmconnection_dso, "DdmConnection_start");
214663f165fd6b86d04be94d4023e845e98560504a96Keun young Park    if (!DdmConnection_start) {
214763f165fd6b86d04be94d4023e845e98560504a96Keun young Park        dlclose(libddmconnection_dso);
214863f165fd6b86d04be94d4023e845e98560504a96Keun young Park        return false;
214963f165fd6b86d04be94d4023e845e98560504a96Keun young Park    }
215063f165fd6b86d04be94d4023e845e98560504a96Keun young Park    (*DdmConnection_start)(getServiceName());
215163f165fd6b86d04be94d4023e845e98560504a96Keun young Park    return true;
215263f165fd6b86d04be94d4023e845e98560504a96Keun young Park}
215363f165fd6b86d04be94d4023e845e98560504a96Keun young Park
2154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::onTransact(
2155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
2156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (code) {
2158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case CREATE_CONNECTION:
2159698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        case SET_TRANSACTION_STATE:
2160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case BOOT_FINISHED:
21618e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross        case BLANK:
21628e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross        case UNBLANK:
2163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        {
2164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // codes that require permission check
2165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            IPCThreadState* ipc = IPCThreadState::self();
2166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int pid = ipc->getCallingPid();
2167a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian            const int uid = ipc->getCallingUid();
216899b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
216999b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) {
2170e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block                ALOGE("Permission Denial: "
2171375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                        "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
2172375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                return PERMISSION_DENIED;
2173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
21741b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
21751b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
21761b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        case CAPTURE_SCREEN:
21771b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
21781b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            // codes that require permission check
21791b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
21801b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int pid = ipc->getCallingPid();
21811b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int uid = ipc->getCallingUid();
218299b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
218399b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) {
2184e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block                ALOGE("Permission Denial: "
21851b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                        "can't read framebuffer pid=%d, uid=%d", pid, uid);
21861b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                return PERMISSION_DENIED;
21871b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            }
21881b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
2189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
2190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
21911b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
2192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
2193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
2194b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        CHECK_INTERFACE(ISurfaceComposer, data, reply);
219599ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten        if (CC_UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) {
2196375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
2197375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int pid = ipc->getCallingPid();
2198375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int uid = ipc->getCallingUid();
2199e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block            ALOGE("Permission Denial: "
2200375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                    "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
2201edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return PERMISSION_DENIED;
2202edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
2203edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int n;
2204edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        switch (code) {
220501b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian            case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE
220635b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian            case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE
2207edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
2208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1002:  // SHOW_UPDATES
2209edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                n = data.readInt32();
2210edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDebugRegion = n ? n : (mDebugRegion ? 0 : 1);
221153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
221253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
2213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
2214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1004:{ // repaint everything
221553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
2216cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
2217cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            }
2218cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            case 1005:{ // force transaction
2219e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                setTransactionFlags(
2220e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        eTransactionNeeded|
2221e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        eDisplayTransactionNeeded|
2222e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        eTraversalNeeded);
2223cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
2224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
22254d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            case 1006:{ // send empty update
22264d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian                signalRefresh();
22274d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian                return NO_ERROR;
22284d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            }
222953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian            case 1008:  // toggle use of hw composer
223053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                n = data.readInt32();
223153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                mDebugDisableHWC = n ? 1 : 0;
223253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
223353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
223453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                return NO_ERROR;
2235a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian            case 1009:  // toggle use of transform hint
2236a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                n = data.readInt32();
2237a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                mDebugDisableTransformHint = n ? 1 : 0;
2238a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                invalidateHwcGeometry();
2239a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                repaintEverything();
2240a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                return NO_ERROR;
2241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1010:  // interrogate.
224201b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian                reply->writeInt32(0);
2243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(0);
2244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(mDebugRegion);
2245b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                reply->writeInt32(0);
224612839bee29bdcc65731b4d42029cc59e2320c5c4Dianne Hackborn                reply->writeInt32(mDebugDisableHWC);
2247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
2248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1013: {
2249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                Mutex::Autolock _l(mStateLock);
22504297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                sp<const DisplayDevice> hw(getDefaultDisplayDevice());
22514297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                reply->writeInt32(hw->getPageFlipCount());
2252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
2253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return NO_ERROR;
2254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
2255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return err;
2257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
225953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopianvoid SurfaceFlinger::repaintEverything() {
226087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    android_atomic_or(1, &mRepaintEverything);
226199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    signalTransaction();
226253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian}
226353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian
226459119e658a12279e8fff508f8773843de2d90917Mathias Agopian// ---------------------------------------------------------------------------
226559119e658a12279e8fff508f8773843de2d90917Mathias Agopian
22663ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopianstatus_t SurfaceFlinger::renderScreenToTexture(uint32_t layerStack,
2267118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        GLuint* textureName, GLfloat* uOut, GLfloat* vOut)
2268118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{
2269118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    Mutex::Autolock _l(mStateLock);
22703ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    return renderScreenToTextureLocked(layerStack, textureName, uOut, vOut);
2271118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
2272118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
22733ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopianstatus_t SurfaceFlinger::renderScreenToTextureLocked(uint32_t layerStack,
22749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        GLuint* textureName, GLfloat* uOut, GLfloat* vOut)
227559119e658a12279e8fff508f8773843de2d90917Mathias Agopian{
227622ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian    ATRACE_CALL();
227722ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian
227859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
227959119e658a12279e8fff508f8773843de2d90917Mathias Agopian        return INVALID_OPERATION;
228059119e658a12279e8fff508f8773843de2d90917Mathias Agopian
228159119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // get screen geometry
22823ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    // FIXME: figure out what it means to have a screenshot texture w/ multi-display
22833ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    sp<const DisplayDevice> hw(getDefaultDisplayDevice());
22844297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const uint32_t hw_w = hw->getWidth();
22854297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const uint32_t hw_h = hw->getHeight();
228659119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLfloat u = 1;
228759119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLfloat v = 1;
228859119e658a12279e8fff508f8773843de2d90917Mathias Agopian
228959119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // make sure to clear all GL error flags
229059119e658a12279e8fff508f8773843de2d90917Mathias Agopian    while ( glGetError() != GL_NO_ERROR ) ;
229159119e658a12279e8fff508f8773843de2d90917Mathias Agopian
229259119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // create a FBO
229359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLuint name, tname;
229459119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glGenTextures(1, &tname);
229559119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
2296a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2297a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
22989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
22999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            hw_w, hw_h, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
230059119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (glGetError() != GL_NO_ERROR) {
2301015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian        while ( glGetError() != GL_NO_ERROR ) ;
230259119e658a12279e8fff508f8773843de2d90917Mathias Agopian        GLint tw = (2 << (31 - clz(hw_w)));
230359119e658a12279e8fff508f8773843de2d90917Mathias Agopian        GLint th = (2 << (31 - clz(hw_h)));
23049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
23059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian                tw, th, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
230659119e658a12279e8fff508f8773843de2d90917Mathias Agopian        u = GLfloat(hw_w) / tw;
230759119e658a12279e8fff508f8773843de2d90917Mathias Agopian        v = GLfloat(hw_h) / th;
230859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    }
230959119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glGenFramebuffersOES(1, &name);
231059119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
23119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES,
23129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0);
231359119e658a12279e8fff508f8773843de2d90917Mathias Agopian
23149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // redraw the screen entirely...
2315c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_EXTERNAL_OES);
2316c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_2D);
23179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glClearColor(0,0,0,1);
23189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glClear(GL_COLOR_BUFFER_BIT);
2319a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glMatrixMode(GL_MODELVIEW);
2320a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glLoadIdentity();
23214297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const Vector< sp<LayerBase> >& layers(hw->getVisibleLayersSortedByZ());
23229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const size_t count = layers.size();
23239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (size_t i=0 ; i<count ; ++i) {
23249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
2325fcb239d3dac8bc80f28177f1951611c1d43286ffMathias Agopian        layer->draw(hw);
23269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
232759119e658a12279e8fff508f8773843de2d90917Mathias Agopian
23284297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->compositionComplete();
2329118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
23309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // back to main framebuffer
23319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
23329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDeleteFramebuffersOES(1, &name);
233359119e658a12279e8fff508f8773843de2d90917Mathias Agopian
23349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *textureName = tname;
23359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *uOut = u;
23369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *vOut = v;
23379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
23389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
233959119e658a12279e8fff508f8773843de2d90917Mathias Agopian
23409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// ---------------------------------------------------------------------------
23419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
23429d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brownstatus_t SurfaceFlinger::captureScreenImplLocked(const sp<IBinder>& display,
234374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        sp<IMemoryHeap>* heap,
234474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t* w, uint32_t* h, PixelFormat* f,
2345bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t sw, uint32_t sh,
2346bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ, uint32_t maxLayerZ)
234774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{
2348fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian    ATRACE_CALL();
2349fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian
235074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    status_t result = PERMISSION_DENIED;
235174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
23523b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject()) {
235374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return INVALID_OPERATION;
23543b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
235574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
235674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // get screen geometry
23573ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    sp<const DisplayDevice> hw(getDisplayDevice(display));
23584297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const uint32_t hw_w = hw->getWidth();
23594297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const uint32_t hw_h = hw->getHeight();
236074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
23613b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    // if we have secure windows on this display, never allow the screen capture
23624297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    if (hw->getSecureLayerVisible()) {
2363ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian        ALOGW("FB is protected: PERMISSION_DENIED");
23643b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        return PERMISSION_DENIED;
23653b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
23663b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
23673b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    if ((sw > hw_w) || (sh > hw_h)) {
2368ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian        ALOGE("size mismatch (%d, %d) > (%d, %d)", sw, sh, hw_w, hw_h);
236974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return BAD_VALUE;
23703b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
237174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
237274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    sw = (!sw) ? hw_w : sw;
237374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    sh = (!sh) ? hw_h : sh;
237474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const size_t size = sw * sh * 4;
2375fcb239d3dac8bc80f28177f1951611c1d43286ffMathias Agopian    const bool filtering = sw != hw_w || sh != hw_h;
237674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
2377ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian//    ALOGD("screenshot: sw=%d, sh=%d, minZ=%d, maxZ=%d",
2378ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian//            sw, sh, minLayerZ, maxLayerZ);
2379c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
238074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // make sure to clear all GL error flags
238174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    while ( glGetError() != GL_NO_ERROR ) ;
238274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
238374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // create a FBO
238474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    GLuint name, tname;
238574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glGenRenderbuffersOES(1, &tname);
238674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindRenderbufferOES(GL_RENDERBUFFER_OES, tname);
238774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA8_OES, sw, sh);
2388fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian
238974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glGenFramebuffersOES(1, &name);
239074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
239174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES,
239274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, tname);
239374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
239474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
2395c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
239674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    if (status == GL_FRAMEBUFFER_COMPLETE_OES) {
239774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
239874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // invert everything, b/c glReadPixel() below will invert the FB
239974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glViewport(0, 0, sw, sh);
240074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_PROJECTION);
240174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glPushMatrix();
240274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glLoadIdentity();
2403ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian        glOrthof(0, hw_w, hw_h, 0, 0, 1);
240474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_MODELVIEW);
240574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
240674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // redraw the screen entirely...
240774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glClearColor(0,0,0,1);
240874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
2409f653b897a449e10d6cbfb6e0812f7b0bb02d6482Mathias Agopian
24103ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian        const Vector< sp<LayerBase> >& layers(hw->getVisibleLayersSortedByZ());
24119575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        const size_t count = layers.size();
241274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        for (size_t i=0 ; i<count ; ++i) {
241374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            const sp<LayerBase>& layer(layers[i]);
24143ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian            const uint32_t z = layer->drawingState().z;
24153ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian            if (z >= minLayerZ && z <= maxLayerZ) {
24163ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian                if (filtering) layer->setFiltering(true);
24173ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian                layer->draw(hw);
24183ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian                if (filtering) layer->setFiltering(false);
2419bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian            }
242074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        }
242174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
242274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // check for errors and return screen capture
242374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        if (glGetError() != GL_NO_ERROR) {
242474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // error while rendering
242574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            result = INVALID_OPERATION;
242674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        } else {
242774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // allocate shared memory large enough to hold the
242874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // screen capture
242974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            sp<MemoryHeapBase> base(
243074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    new MemoryHeapBase(size, 0, "screen-capture") );
243174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            void* const ptr = base->getBase();
243274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            if (ptr) {
243374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                // capture the screen with glReadPixels()
2434fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian                ScopedTrace _t(ATRACE_TAG, "glReadPixels");
243574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                glReadPixels(0, 0, sw, sh, GL_RGBA, GL_UNSIGNED_BYTE, ptr);
243674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                if (glGetError() == GL_NO_ERROR) {
243774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *heap = base;
243874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *w = sw;
243974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *h = sh;
244074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *f = PIXEL_FORMAT_RGBA_8888;
244174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    result = NO_ERROR;
244274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                }
244374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            } else {
244474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                result = NO_MEMORY;
244574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            }
244674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        }
244774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glViewport(0, 0, hw_w, hw_h);
244874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_PROJECTION);
244974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glPopMatrix();
245074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_MODELVIEW);
245174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    } else {
245274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        result = BAD_VALUE;
245374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    }
245474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
245574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // release FBO resources
245674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
245774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glDeleteRenderbuffersOES(1, &tname);
245874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glDeleteFramebuffersOES(1, &name);
2459e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian
24604297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->compositionComplete();
2461e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian
2462ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian//    ALOGD("screenshot: result = %s", result<0 ? strerror(result) : "OK");
2463c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
246474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    return result;
246574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian}
246674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
246774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
24689d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brownstatus_t SurfaceFlinger::captureScreen(const sp<IBinder>& display,
24691b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        sp<IMemoryHeap>* heap,
247074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t* width, uint32_t* height, PixelFormat* format,
2471bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t sw, uint32_t sh,
2472bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ, uint32_t maxLayerZ)
24731b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian{
24749d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown    if (CC_UNLIKELY(display == 0))
24751b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        return BAD_VALUE;
24761b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
24771b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
24781b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        return INVALID_OPERATION;
24791b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
24801b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    class MessageCaptureScreen : public MessageBase {
24811b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        SurfaceFlinger* flinger;
24829d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown        sp<IBinder> display;
24831b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        sp<IMemoryHeap>* heap;
24841b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        uint32_t* w;
24851b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        uint32_t* h;
24861b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        PixelFormat* f;
248774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t sw;
248874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t sh;
2489bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ;
2490bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t maxLayerZ;
24911b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        status_t result;
24921b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    public:
24939d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown        MessageCaptureScreen(SurfaceFlinger* flinger, const sp<IBinder>& display,
249474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                sp<IMemoryHeap>* heap, uint32_t* w, uint32_t* h, PixelFormat* f,
2495bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                uint32_t sw, uint32_t sh,
2496bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                uint32_t minLayerZ, uint32_t maxLayerZ)
24979d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown            : flinger(flinger), display(display),
2498bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              heap(heap), w(w), h(h), f(f), sw(sw), sh(sh),
2499bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              minLayerZ(minLayerZ), maxLayerZ(maxLayerZ),
2500bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              result(PERMISSION_DENIED)
25011b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
25021b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
25031b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        status_t getResult() const {
25041b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            return result;
25051b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
25061b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        virtual bool handler() {
25071b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
25089d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown            result = flinger->captureScreenImplLocked(display,
2509bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                    heap, w, h, f, sw, sh, minLayerZ, maxLayerZ);
25101b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            return true;
25111b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
25121b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    };
25131b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
25141b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    sp<MessageBase> msg = new MessageCaptureScreen(this,
25159d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown            display, heap, width, height, format, sw, sh, minLayerZ, maxLayerZ);
25161b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    status_t res = postMessageSync(msg);
25171b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    if (res == NO_ERROR) {
25181b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        res = static_cast<MessageCaptureScreen*>( msg.get() )->getResult();
25191b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    }
25201b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    return res;
25211b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian}
25221b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
25231b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// ---------------------------------------------------------------------------
25241b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
2525921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::LayerVector::LayerVector() {
2526921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
2527921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
2528921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::LayerVector::LayerVector(const LayerVector& rhs)
2529921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    : SortedVector<sp<LayerBase> >(rhs) {
2530921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
2531921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
2532921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianint SurfaceFlinger::LayerVector::do_compare(const void* lhs,
2533921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    const void* rhs) const
2534edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2535be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    // sort layers per layer-stack, then by z-order and finally by sequence
2536921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    const sp<LayerBase>& l(*reinterpret_cast<const sp<LayerBase>*>(lhs));
2537921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    const sp<LayerBase>& r(*reinterpret_cast<const sp<LayerBase>*>(rhs));
2538be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian
2539be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    uint32_t ls = l->currentState().layerStack;
2540be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    uint32_t rs = r->currentState().layerStack;
2541be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    if (ls != rs)
2542be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian        return ls - rs;
2543be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian
2544921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    uint32_t lz = l->currentState().z;
2545921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    uint32_t rz = r->currentState().z;
2546be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    if (lz != rz)
2547be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian        return lz - rz;
2548be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian
2549be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    return l->sequence - r->sequence;
2550921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
2551921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
2552921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian// ---------------------------------------------------------------------------
2553921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
25543ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias AgopianSurfaceFlinger::DisplayDeviceState::DisplayDeviceState()
25553ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    : type(DisplayDevice::DISPLAY_ID_INVALID) {
2556e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
2557e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
25583ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias AgopianSurfaceFlinger::DisplayDeviceState::DisplayDeviceState(DisplayDevice::DisplayType type)
25593ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    : type(type), layerStack(0), orientation(0) {
2560da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian    viewport.makeInvalid();
2561da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian    frame.makeInvalid();
2562b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
25637303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
2564b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// ---------------------------------------------------------------------------
256596f0819f81293076e652792794a961543e6750d7Mathias Agopian
2566edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
2567