SurfaceFlinger.cpp revision 2adaf04fab35cf47c824d74d901b54094e01ccd3
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>
404803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#include <gui/GuiConfig.h>
411a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <gui/IDisplayEventConnection.h>
42921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <gui/SurfaceTextureClient.h>
43392edd88cb63d71a21a86a02cf9c56ac97637128Jamie Gennis#include <gui/GraphicBufferAlloc.h>
44921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
45921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <ui/GraphicBufferAllocator.h>
46921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <ui/PixelFormat.h>
474803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#include <ui/UiConfig.h>
48d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
49cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian#include <utils/misc.h>
50edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String8.h>
51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String16.h>
52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/StopWatch.h>
531c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#include <utils/Trace.h>
54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
55921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <private/android_filesystem_config.h>
56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
57edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h"
5890ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include "DdmConnection.h"
590f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian#include "DisplayDevice.h"
60db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian#include "Client.h"
61d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian#include "EventThread.h"
621f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian#include "GLExtensions.h"
63edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h"
64edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerDim.h"
65118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian#include "LayerScreenshot.h"
66edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h"
67edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
68a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#include "DisplayHardware/FramebufferSurface.h"
69a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian#include "DisplayHardware/HWComposer.h"
70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
71a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
72bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian#define EGL_VERSION_HW_ANDROID  0x3143
73bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
74edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DISPLAY_COUNT       1
75edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
76edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
77edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
78edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
7999b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sHardwareTest("android.permission.HARDWARE_TEST");
8099b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER");
8199b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER");
8299b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sDump("android.permission.DUMP");
8399b49840d309727678b77403d6cc9f920111623fMathias Agopian
8499b49840d309727678b77403d6cc9f920111623fMathias Agopian// ---------------------------------------------------------------------------
8599b49840d309727678b77403d6cc9f920111623fMathias Agopian
86edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::SurfaceFlinger()
87edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    :   BnSurfaceComposer(), Thread(false),
88edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mTransactionFlags(0),
892d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        mTransactionPending(false),
902d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        mAnimTransactionPending(false),
91076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved(false),
9252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        mRepaintEverything(0),
93edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mBootTime(systemTime()),
94edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mVisibleRegionsDirty(false),
95a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        mHwWorkListDirty(false),
96edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDebugRegion(0),
978afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian        mDebugDDMS(0),
9873d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian        mDebugDisableHWC(0),
99a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian        mDebugDisableTransformHint(0),
1009795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInSwapBuffers(0),
1019795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastSwapBufferTime(0),
1029795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInTransaction(0),
1039795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastTransactionTime(0),
1045f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        mBootFinished(false)
105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
106a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI("SurfaceFlinger is starting");
107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // debugging stuff...
109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char value[PROPERTY_VALUE_MAX];
1108afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    property_get("debug.sf.showupdates", value, "0");
112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDebugRegion = atoi(value);
1138afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
1148afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    property_get("debug.sf.ddms", value, "0");
1158afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    mDebugDDMS = atoi(value);
1168afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    if (mDebugDDMS) {
11763f165fd6b86d04be94d4023e845e98560504a96Keun young Park        if (!startDdmConnection()) {
11863f165fd6b86d04be94d4023e845e98560504a96Keun young Park            // start failed, and DDMS debugging not enabled
11963f165fd6b86d04be94d4023e845e98560504a96Keun young Park            mDebugDDMS = 0;
12063f165fd6b86d04be94d4023e845e98560504a96Keun young Park        }
1218afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    }
122c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    ALOGI_IF(mDebugRegion, "showupdates enabled");
123c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    ALOGI_IF(mDebugDDMS, "DDMS debugging enabled");
124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
125edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
12699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::onFirstRef()
12799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
12899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.init(this);
12999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
13099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY);
13199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
13299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // Wait for the main thread to be done with its initialization
13399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mReadyToRunBarrier.wait();
13499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
13599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
13699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::~SurfaceFlinger()
138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
139a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
140a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
141a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglTerminate(display);
142edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
143edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
14499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::binderDied(const wp<IBinder>& who)
14599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
14699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // the window manager died on us. prepare its eulogy.
14799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
14813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    // restore initial conditions (default device unblank, etc)
14913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    initializeDisplays();
15099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
15199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // restart the boot-animation
152a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    startBootAnim();
15399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
15499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
1557e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopiansp<ISurfaceComposerClient> SurfaceFlinger::createConnection()
156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
15796f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<ISurfaceComposerClient> bclient;
15896f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<Client> client(new Client(this));
15996f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = client->initCheck();
16096f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR) {
16196f0819f81293076e652792794a961543e6750d7Mathias Agopian        bclient = client;
162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return bclient;
164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
166dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennissp<IBinder> SurfaceFlinger::createDisplay(const String8& displayName,
167dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis        bool secure)
168e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{
169e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    class DisplayToken : public BBinder {
170e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        sp<SurfaceFlinger> flinger;
171e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        virtual ~DisplayToken() {
172e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             // no more references, this display must be terminated
173e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             Mutex::Autolock _l(flinger->mStateLock);
174e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             flinger->mCurrentState.displays.removeItem(this);
175e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             flinger->setTransactionFlags(eDisplayTransactionNeeded);
176e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian         }
177e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian     public:
178e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        DisplayToken(const sp<SurfaceFlinger>& flinger)
179e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            : flinger(flinger) {
180e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
181e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    };
182e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
183e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    sp<BBinder> token = new DisplayToken(this);
184e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
185e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    Mutex::Autolock _l(mStateLock);
1863ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    DisplayDeviceState info(DisplayDevice::DISPLAY_VIRTUAL);
1878dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden    info.displayName = displayName;
188dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    info.isSecure = secure;
189e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    mCurrentState.displays.add(token, info);
190e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
191e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return token;
192e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
193e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
194692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hallvoid SurfaceFlinger::createBuiltinDisplayLocked(DisplayDevice::DisplayType type) {
195692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    ALOGW_IF(mBuiltinDisplays[type],
196692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall            "Overwriting display token for display type %d", type);
197692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    mBuiltinDisplays[type] = new BBinder();
198692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    DisplayDeviceState info(type);
199692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    // All non-virtual displays are currently considered secure.
200692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    info.isSecure = true;
201692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    mCurrentState.displays.add(mBuiltinDisplays[type], info);
202692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall}
203692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall
204e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopiansp<IBinder> SurfaceFlinger::getBuiltInDisplay(int32_t id) {
2053ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    if (uint32_t(id) >= DisplayDevice::NUM_DISPLAY_TYPES) {
206e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        ALOGE("getDefaultDisplay: id=%d is not a valid default display id", id);
207e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        return NULL;
208e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
209692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    return mBuiltinDisplays[id];
210e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
211e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
2129a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc()
2139a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis{
2149a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc());
2159a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    return gba;
2169a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis}
217b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::bootFinished()
219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t now = systemTime();
221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t duration = now - mBootTime;
222a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
2233330b203039dea366d4981db1408a460134b2d2cMathias Agopian    mBootFinished = true;
2241f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
2251f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // wait patiently for the window manager death
2261f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    const String16 name("window");
2271f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    sp<IBinder> window(defaultServiceManager()->getService(name));
2281f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    if (window != 0) {
229921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        window->linkToDeath(static_cast<IBinder::DeathRecipient*>(this));
2301f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    }
2311f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
2321f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // stop boot animation
233a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // formerly we would just kill the process, but we now ask it to exit so it
234a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // can choose where to stop the animation.
235a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("service.bootanim.exit", "1");
236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
238921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianvoid SurfaceFlinger::deleteTextureAsync(GLuint texture) {
239921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    class MessageDestroyGLTexture : public MessageBase {
240921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        GLuint texture;
241921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    public:
242921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        MessageDestroyGLTexture(GLuint texture)
243921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian            : texture(texture) {
244921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        }
245921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        virtual bool handler() {
246921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian            glDeleteTextures(1, &texture);
247921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian            return true;
248921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        }
249921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    };
250921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    postMessageAsync(new MessageDestroyGLTexture(texture));
251921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
252921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
253722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopianstatus_t SurfaceFlinger::selectConfigForAttribute(
254a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        EGLDisplay dpy,
255a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        EGLint const* attrs,
256722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian        EGLint attribute, EGLint wanted,
257a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        EGLConfig* outConfig)
258a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian{
259a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLConfig config = NULL;
260a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLint numConfigs = -1, n=0;
261a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglGetConfigs(dpy, NULL, 0, &numConfigs);
262a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLConfig* const configs = new EGLConfig[numConfigs];
263a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglChooseConfig(dpy, attrs, configs, numConfigs, &n);
264cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian
265722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian    if (n) {
266722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian        if (attribute != EGL_NONE) {
267722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian            for (int i=0 ; i<n ; i++) {
268722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian                EGLint value = 0;
269722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian                eglGetConfigAttrib(dpy, configs[i], attribute, &value);
270722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian                if (wanted == value) {
271722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian                    *outConfig = configs[i];
272722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian                    delete [] configs;
273722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian                    return NO_ERROR;
274722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian                }
275722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian            }
276722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian        } else {
277722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian            // just pick the first one
278722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian            *outConfig = configs[0];
279a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            delete [] configs;
280a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            return NO_ERROR;
281a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        }
282a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    }
283a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    delete [] configs;
284a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    return NAME_NOT_FOUND;
285edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
286edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
287722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopianclass EGLAttributeVector {
288722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian    struct Attribute;
289722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian    class Adder;
290722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian    friend class Adder;
291722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian    KeyedVector<Attribute, EGLint> mList;
292722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian    struct Attribute {
293722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian        Attribute() {};
294722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian        Attribute(EGLint v) : v(v) { }
295722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian        EGLint v;
296722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian        bool operator < (const Attribute& other) const {
297722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian            // this places EGL_NONE at the end
298722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian            EGLint lhs(v);
299722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian            EGLint rhs(other.v);
300722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian            if (lhs == EGL_NONE) lhs = 0x7FFFFFFF;
301722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian            if (rhs == EGL_NONE) rhs = 0x7FFFFFFF;
302722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian            return lhs < rhs;
303722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian        }
304722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian    };
305722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian    class Adder {
306722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian        friend class EGLAttributeVector;
307722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian        EGLAttributeVector& v;
308722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian        EGLint attribute;
309722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian        Adder(EGLAttributeVector& v, EGLint attribute)
310722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian            : v(v), attribute(attribute) {
311722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian        }
312722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian    public:
313722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian        void operator = (EGLint value) {
314722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian            if (attribute != EGL_NONE) {
315722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian                v.mList.add(attribute, value);
316722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian            }
317722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian        }
318722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian        operator EGLint () const { return v.mList[attribute]; }
319722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian    };
320722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopianpublic:
321722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian    EGLAttributeVector() {
322722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian        mList.add(EGL_NONE, EGL_NONE);
323722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian    }
324722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian    void remove(EGLint attribute) {
325722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian        if (attribute != EGL_NONE) {
326722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian            mList.removeItem(attribute);
327722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian        }
328722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian    }
329722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian    Adder operator [] (EGLint attribute) {
330722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian        return Adder(*this, attribute);
331722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian    }
332722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian    EGLint operator [] (EGLint attribute) const {
333722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian       return mList[attribute];
334722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian    }
335722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian    // cast-operator to (EGLint const*)
336722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian    operator EGLint const* () const { return &mList.keyAt(0).v; }
337722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian};
338722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian
339a49126087b4494f4ef50873f3a3f6727265f6621Mathias AgopianEGLConfig SurfaceFlinger::selectEGLConfig(EGLDisplay display, EGLint nativeVisualId) {
340a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // select our EGLConfig. It must support EGL_RECORDABLE_ANDROID if
341a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // it is to be used with WIFI displays
342a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLConfig config;
343a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLint dummy;
344a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    status_t err;
345da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
346722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian    EGLAttributeVector attribs;
347722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian    attribs[EGL_SURFACE_TYPE]               = EGL_WINDOW_BIT;
348722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian    attribs[EGL_RECORDABLE_ANDROID]         = EGL_TRUE;
349722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian    attribs[EGL_FRAMEBUFFER_TARGET_ANDROID] = EGL_TRUE;
350722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian    attribs[EGL_RED_SIZE]                   = 8;
351722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian    attribs[EGL_GREEN_SIZE]                 = 8;
352722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian    attribs[EGL_BLUE_SIZE]                  = 8;
353722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian
354722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian    err = selectConfigForAttribute(display, attribs, EGL_NONE, EGL_NONE, &config);
355722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian    if (!err)
356722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian        goto success;
357722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian
358722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian    // maybe we failed because of EGL_FRAMEBUFFER_TARGET_ANDROID
359722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian    ALOGW("no suitable EGLConfig found, trying without EGL_FRAMEBUFFER_TARGET_ANDROID");
360722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian    attribs.remove(EGL_FRAMEBUFFER_TARGET_ANDROID);
361722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian    err = selectConfigForAttribute(display, attribs,
362722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian            EGL_NATIVE_VISUAL_ID, nativeVisualId, &config);
363f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall    if (!err)
364f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall        goto success;
365f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall
366f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall    // maybe we failed because of EGL_RECORDABLE_ANDROID
367f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall    ALOGW("no suitable EGLConfig found, trying without EGL_RECORDABLE_ANDROID");
368722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian    attribs.remove(EGL_RECORDABLE_ANDROID);
369722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian    err = selectConfigForAttribute(display, attribs,
370722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian            EGL_NATIVE_VISUAL_ID, nativeVisualId, &config);
371f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall    if (!err)
372f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall        goto success;
373f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall
374f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall    // allow less than 24-bit color; the non-gpu-accelerated emulator only
375f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall    // supports 16-bit color
376f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall    ALOGW("no suitable EGLConfig found, trying with 16-bit color allowed");
377722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian    attribs.remove(EGL_RED_SIZE);
378722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian    attribs.remove(EGL_GREEN_SIZE);
379722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian    attribs.remove(EGL_BLUE_SIZE);
380722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian    err = selectConfigForAttribute(display, attribs,
381722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian            EGL_NATIVE_VISUAL_ID, nativeVisualId, &config);
382f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall    if (!err)
383f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall        goto success;
384f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall
385f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall    // this EGL is too lame for Android
386f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall    ALOGE("no suitable EGLConfig found, giving up");
387f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall
388f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall    return 0;
389f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall
390f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hallsuccess:
391f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall    if (eglGetConfigAttrib(display, config, EGL_CONFIG_CAVEAT, &dummy))
392a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        ALOGW_IF(dummy == EGL_SLOW_CONFIG, "EGL_SLOW_CONFIG selected!");
393a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    return config;
394a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
395edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
396a49126087b4494f4ef50873f3a3f6727265f6621Mathias AgopianEGLContext SurfaceFlinger::createGLContext(EGLDisplay display, EGLConfig config) {
397a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // Also create our EGLContext
398a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLint contextAttributes[] = {
399a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#ifdef EGL_IMG_context_priority
400a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#ifdef HAS_CONTEXT_PRIORITY
401a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#warning "using EGL_IMG_context_priority"
402a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_HIGH_IMG,
403a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#endif
404a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#endif
405a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            EGL_NONE, EGL_NONE
406a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    };
407a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLContext ctxt = eglCreateContext(display, config, NULL, contextAttributes);
408a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGE_IF(ctxt==EGL_NO_CONTEXT, "EGLContext creation failed");
409a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    return ctxt;
410a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
411edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
412cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopianvoid SurfaceFlinger::initializeGL(EGLDisplay display) {
413a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    GLExtensions& extensions(GLExtensions::getInstance());
414a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    extensions.initWithGLStrings(
415a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            glGetString(GL_VENDOR),
416a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            glGetString(GL_RENDERER),
417a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            glGetString(GL_VERSION),
418a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            glGetString(GL_EXTENSIONS),
419a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            eglQueryString(display, EGL_VENDOR),
420a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            eglQueryString(display, EGL_VERSION),
421a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            eglQueryString(display, EGL_EXTENSIONS));
4228b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
423a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
424a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    glGetIntegerv(GL_MAX_VIEWPORT_DIMS, mMaxViewportDims);
4257303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
426edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
4278b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber    glPixelStorei(GL_PACK_ALIGNMENT, 4);
428edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glEnableClientState(GL_VERTEX_ARRAY);
429edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glShadeModel(GL_FLAT);
430edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_DITHER);
431edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_CULL_FACE);
432edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
433a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    struct pack565 {
434a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        inline uint16_t operator() (int r, int g, int b) const {
435a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            return (r<<11)|(g<<5)|b;
436a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        }
437a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    } pack565;
438a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
4399575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    const uint16_t protTexData[] = { pack565(0x03, 0x03, 0x03) };
4409575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glGenTextures(1, &mProtectedTexName);
4419575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glBindTexture(GL_TEXTURE_2D, mProtectedTexName);
4429575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
4439575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4449575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
4459575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
4469575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0,
4479575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis            GL_RGB, GL_UNSIGNED_SHORT_5_6_5, protTexData);
448edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
449a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // print some debugging info
450a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLint r,g,b,a;
451a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglGetConfigAttrib(display, mEGLConfig, EGL_RED_SIZE,   &r);
452a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglGetConfigAttrib(display, mEGLConfig, EGL_GREEN_SIZE, &g);
453a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglGetConfigAttrib(display, mEGLConfig, EGL_BLUE_SIZE,  &b);
454a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglGetConfigAttrib(display, mEGLConfig, EGL_ALPHA_SIZE, &a);
455a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("EGL informations:");
456a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("vendor    : %s", extensions.getEglVendor());
457a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("version   : %s", extensions.getEglVersion());
458a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("extensions: %s", extensions.getEglExtension());
459a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("Client API: %s", eglQueryString(display, EGL_CLIENT_APIS)?:"Not Supported");
460a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("EGLSurface: %d-%d-%d-%d, config=%p", r, g, b, a, mEGLConfig);
461a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("OpenGL ES informations:");
462a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("vendor    : %s", extensions.getVendor());
463a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("renderer  : %s", extensions.getRenderer());
464a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("version   : %s", extensions.getVersion());
465a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("extensions: %s", extensions.getExtension());
466a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("GL_MAX_TEXTURE_SIZE = %d", mMaxTextureSize);
467a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("GL_MAX_VIEWPORT_DIMS = %d x %d", mMaxViewportDims[0], mMaxViewportDims[1]);
468a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
469a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
470a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianstatus_t SurfaceFlinger::readyToRun()
471a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian{
472a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI(  "SurfaceFlinger's main thread ready to run. "
473a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            "Initializing graphics H/W...");
474a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
475692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    Mutex::Autolock _l(mStateLock);
476692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall
477b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden    // initialize EGL for the default display
47834a09ba1efd706323a15633da5044b352988eb5fJesse Hall    mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
47934a09ba1efd706323a15633da5044b352988eb5fJesse Hall    eglInitialize(mEGLDisplay, NULL, NULL);
480a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
481b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden    // Initialize the H/W composer object.  There may or may not be an
482b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden    // actual hardware composer underneath.
483b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden    mHwc = new HWComposer(this,
484b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden            *static_cast<HWComposer::EventHandler *>(this));
485b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden
486a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // initialize the config and context
487cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian    EGLint format = mHwc->getVisualID();
48834a09ba1efd706323a15633da5044b352988eb5fJesse Hall    mEGLConfig  = selectEGLConfig(mEGLDisplay, format);
48934a09ba1efd706323a15633da5044b352988eb5fJesse Hall    mEGLContext = createGLContext(mEGLDisplay, mEGLConfig);
490a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
491da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian    LOG_ALWAYS_FATAL_IF(mEGLContext == EGL_NO_CONTEXT,
492da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian            "couldn't create EGLContext");
493da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
494cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian    // initialize our non-virtual displays
4953ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    for (size_t i=0 ; i<DisplayDevice::NUM_DISPLAY_TYPES ; i++) {
496f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian        DisplayDevice::DisplayType type((DisplayDevice::DisplayType)i);
497f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian        // set-up the displays that are already connected
4989e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian        if (mHwc->isConnected(i) || type==DisplayDevice::DISPLAY_PRIMARY) {
499dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis            // All non-virtual displays are currently considered secure.
500dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis            bool isSecure = true;
501692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall            createBuiltinDisplayLocked(type);
502692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall            wp<IBinder> token = mBuiltinDisplays[i];
503692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall
504f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian            sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, i);
505f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian            sp<SurfaceTextureClient> stc = new SurfaceTextureClient(
5062adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden                        static_cast< sp<IGraphicBufferProducer> >(fbs->getBufferQueue()));
507f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian            sp<DisplayDevice> hw = new DisplayDevice(this,
508dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis                    type, isSecure, token, stc, fbs, mEGLConfig);
509f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian            if (i > DisplayDevice::DISPLAY_PRIMARY) {
510c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden                // FIXME: currently we don't get blank/unblank requests
511f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian                // for displays other than the main display, so we always
512f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian                // assume a connected display is unblanked.
513c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden                ALOGD("marking display %d as acquired/unblanked", i);
514f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian                hw->acquireScreen();
515f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian            }
516f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian            mDisplays.add(token, hw);
517f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian        }
518e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
519cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian
520f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian    //  we need a GL context current in a few places, when initializing
521f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian    //  OpenGL ES (see below), or creating a layer,
522f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian    //  or when a texture is (asynchronously) destroyed, and for that
523f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian    //  we need a valid surface, so it's convenient to use the main display
524f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian    //  for that.
525db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian    sp<const DisplayDevice> hw(getDefaultDisplayDevice());
526cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian
527a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    //  initialize OpenGL ES
528cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian    DisplayDevice::makeCurrent(mEGLDisplay, hw, mEGLContext);
529cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian    initializeGL(mEGLDisplay);
530d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
531028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian    // start the EventThread
532028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian    mEventThread = new EventThread(this);
533028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian    mEventQueue.setEventThread(mEventThread);
534028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian
53592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    // initialize our drawing state
53692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    mDrawingState = mCurrentState;
5378630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
538cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian
539a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // We're now ready to accept clients...
540d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian    mReadyToRunBarrier.open();
541d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
54213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    // set initial conditions (e.g. unblank default device)
54313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    initializeDisplays();
54413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
545a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    // start boot animation
546a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    startBootAnim();
5478b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
548edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
549edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
550edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5513ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopianint32_t SurfaceFlinger::allocateHwcDisplayId(DisplayDevice::DisplayType type) {
5523ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    return (uint32_t(type) < DisplayDevice::NUM_DISPLAY_TYPES) ?
5533ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian            type : mHwc->allocateDisplayId();
5543ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian}
5553ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian
556a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopianvoid SurfaceFlinger::startBootAnim() {
557a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // start boot animation
558a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("service.bootanim.exit", "0");
559a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("ctl.start", "bootanim");
560a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian}
561a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian
562a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianuint32_t SurfaceFlinger::getMaxTextureSize() const {
563a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    return mMaxTextureSize;
564a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
565a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
566a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianuint32_t SurfaceFlinger::getMaxViewportDims() const {
567a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    return mMaxViewportDims[0] < mMaxViewportDims[1] ?
568a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            mMaxViewportDims[0] : mMaxViewportDims[1];
569a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
570a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
571edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
572d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
573582270d69db94286a248bd829f1ae6f910d45124Jamie Gennisbool SurfaceFlinger::authenticateSurfaceTexture(
5742adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden        const sp<IGraphicBufferProducer>& bufferProducer) const {
575134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    Mutex::Autolock _l(mStateLock);
5762adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden    sp<IBinder> surfaceTextureBinder(bufferProducer->asBinder());
577134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
578134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // Check the visible layer list for the ISurface
579134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
580134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    size_t count = currentLayers.size();
581134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    for (size_t i=0 ; i<count ; i++) {
582134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        const sp<LayerBase>& layer(currentLayers[i]);
583134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        sp<LayerBaseClient> lbc(layer->getLayerBaseClient());
584582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis        if (lbc != NULL) {
585582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder();
586582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            if (lbcBinder == surfaceTextureBinder) {
587582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis                return true;
588582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            }
589134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        }
590134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    }
591134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
592134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // Check the layers in the purgatory.  This check is here so that if a
5932adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden    // GLConsumer gets destroyed before all the clients are done using it,
594582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis    // the error will not be reported as "surface XYZ is not authenticated", but
595134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // will instead fail later on when the client tries to use the surface,
596134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // which should be reported as "surface XYZ returned an -ENODEV".  The
597134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // purgatorized layers are no less authentic than the visible ones, so this
598134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // should not cause any harm.
599134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    size_t purgatorySize =  mLayerPurgatory.size();
600134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    for (size_t i=0 ; i<purgatorySize ; i++) {
601134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
602134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        sp<LayerBaseClient> lbc(layer->getLayerBaseClient());
603582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis        if (lbc != NULL) {
604582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder();
605582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            if (lbcBinder == surfaceTextureBinder) {
606582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis                return true;
607582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            }
608134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        }
609134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    }
610134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
611134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    return false;
612134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis}
613134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
6149d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brownstatus_t SurfaceFlinger::getDisplayInfo(const sp<IBinder>& display, DisplayInfo* info) {
615692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    int32_t type = NAME_NOT_FOUND;
6161604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian    for (int i=0 ; i<DisplayDevice::NUM_DISPLAY_TYPES ; i++) {
617692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall        if (display == mBuiltinDisplays[i]) {
6181604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian            type = i;
6191604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian            break;
6201604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        }
6211604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian    }
6221604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian
6231604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian    if (type < 0) {
6241604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        return type;
625c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian    }
6268b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian
6278b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    const HWComposer& hwc(getHwComposer());
6281604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian    float xdpi = hwc.getDpiX(type);
6291604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian    float ydpi = hwc.getDpiY(type);
6308b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian
6318b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    // TODO: Not sure if display density should handled by SF any longer
6328b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    class Density {
6338b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        static int getDensityFromProperty(char const* propName) {
6348b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            char property[PROPERTY_VALUE_MAX];
6358b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            int density = 0;
6368b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            if (property_get(propName, property, NULL) > 0) {
6378b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian                density = atoi(property);
6388b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            }
6398b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            return density;
6408b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        }
6418b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    public:
6428b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        static int getEmuDensity() {
6438b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            return getDensityFromProperty("qemu.sf.lcd_density"); }
6448b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        static int getBuildDensity()  {
6458b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            return getDensityFromProperty("ro.sf.lcd_density"); }
6468b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    };
6471604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian
6481604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian    if (type == DisplayDevice::DISPLAY_PRIMARY) {
6491604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        // The density of the device is provided by a build property
6501604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        float density = Density::getBuildDensity() / 160.0f;
6511604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        if (density == 0) {
6521604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian            // the build doesn't provide a density -- this is wrong!
6531604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian            // use xdpi instead
6541604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian            ALOGE("ro.sf.lcd_density must be defined as a build property");
6551604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian            density = xdpi / 160.0f;
6561604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        }
6571604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        if (Density::getEmuDensity()) {
6581604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian            // if "qemu.sf.lcd_density" is specified, it overrides everything
6591604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian            xdpi = ydpi = density = Density::getEmuDensity();
6601604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian            density /= 160.0f;
6611604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        }
6621604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        info->density = density;
6631604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian
6641604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        // TODO: this needs to go away (currently needed only by webkit)
6651604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        sp<const DisplayDevice> hw(getDefaultDisplayDevice());
6661604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        info->orientation = hw->getOrientation();
6671604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        getPixelFormatInfo(hw->getFormat(), &info->pixelFormatInfo);
6681604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian    } else {
6691604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        // TODO: where should this value come from?
6701604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        static const int TV_DENSITY = 213;
6711604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        info->density = TV_DENSITY / 160.0f;
6721604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        info->orientation = 0;
6738b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    }
6748b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian
6751604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian    info->w = hwc.getWidth(type);
6761604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian    info->h = hwc.getHeight(type);
6778b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    info->xdpi = xdpi;
6788b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    info->ydpi = ydpi;
6791604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian    info->fps = float(1e9 / hwc.getRefreshPeriod(type));
680dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
681dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    // All non-virtual displays are currently considered secure.
682dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    info->secure = true;
683dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
684888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian    return NO_ERROR;
685c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian}
686c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian
687d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian// ----------------------------------------------------------------------------
688d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
689d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopiansp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection() {
6908aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian    return mEventThread->createEventConnection();
691bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian}
692bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
693edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
69499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
69599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::waitForEvent() {
69699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.waitMessage();
69799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
69899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
69999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalTransaction() {
70099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.invalidate();
70199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
70299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
70399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalLayerUpdate() {
70499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.invalidate();
70599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
70699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
70799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalRefresh() {
70899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.refresh();
70999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
71099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
71199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg,
71299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        nsecs_t reltime, uint32_t flags) {
71399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return mEventQueue.postMessage(msg, reltime);
71499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
71599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
71699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,
71799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        nsecs_t reltime, uint32_t flags) {
71899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    status_t res = mEventQueue.postMessage(msg, reltime);
71999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    if (res == NO_ERROR) {
72099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        msg->wait();
72199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    }
72299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return res;
72399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
724edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
7254fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianbool SurfaceFlinger::threadLoop() {
726edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    waitForEvent();
72799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return true;
72899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
729edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
7303ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopianvoid SurfaceFlinger::onVSyncReceived(int type, nsecs_t timestamp) {
73143601a2dc320a271ff8c3765ff61414a07221635Andy McFadden    if (mEventThread == NULL) {
73243601a2dc320a271ff8c3765ff61414a07221635Andy McFadden        // This is a temporary workaround for b/7145521.  A non-null pointer
73343601a2dc320a271ff8c3765ff61414a07221635Andy McFadden        // does not mean EventThread has finished initializing, so this
73443601a2dc320a271ff8c3765ff61414a07221635Andy McFadden        // is not a correct fix.
73543601a2dc320a271ff8c3765ff61414a07221635Andy McFadden        ALOGW("WARNING: EventThread not started, ignoring vsync");
73643601a2dc320a271ff8c3765ff61414a07221635Andy McFadden        return;
73743601a2dc320a271ff8c3765ff61414a07221635Andy McFadden    }
7383ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    if (uint32_t(type) < DisplayDevice::NUM_DISPLAY_TYPES) {
7393ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian        // we should only receive DisplayDevice::DisplayType from the vsync callback
740148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian        mEventThread->onVSyncReceived(type, timestamp);
741148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian    }
742148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian}
743148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian
744148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopianvoid SurfaceFlinger::onHotplugReceived(int type, bool connected) {
745148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian    if (mEventThread == NULL) {
746148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian        // This is a temporary workaround for b/7145521.  A non-null pointer
747148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian        // does not mean EventThread has finished initializing, so this
748148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian        // is not a correct fix.
749148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian        ALOGW("WARNING: EventThread not started, ignoring hotplug");
750148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian        return;
751148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian    }
7529e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian
753148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian    if (uint32_t(type) < DisplayDevice::NUM_DISPLAY_TYPES) {
7549e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian        Mutex::Autolock _l(mStateLock);
755692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall        if (connected) {
756692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall            createBuiltinDisplayLocked((DisplayDevice::DisplayType)type);
7579e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian        } else {
758692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall            mCurrentState.displays.removeItem(mBuiltinDisplays[type]);
759692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall            mBuiltinDisplays[type].clear();
7609e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian        }
7619e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian        setTransactionFlags(eDisplayTransactionNeeded);
7629e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian
7639e9689c11148521d2c16a121a0b87b062be0714cAndy McFadden        // Defer EventThread notification until SF has updated mDisplays.
7643ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    }
7658630320433bd15aca239522e54e711ef6372ab07Mathias Agopian}
7668630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
76781cd5d3b94d21253a0be925f4ae58cc7f4afeef7Mathias Agopianvoid SurfaceFlinger::eventControl(int disp, int event, int enabled) {
76881cd5d3b94d21253a0be925f4ae58cc7f4afeef7Mathias Agopian    getHwComposer().eventControl(disp, event, enabled);
7698630320433bd15aca239522e54e711ef6372ab07Mathias Agopian}
7708630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
7714fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::onMessageReceived(int32_t what) {
7721c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
77399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    switch (what) {
7744fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    case MessageQueue::INVALIDATE:
7754fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        handleMessageTransaction();
7764fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        handleMessageInvalidate();
7774fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        signalRefresh();
7784fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        break;
7794fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    case MessageQueue::REFRESH:
7804fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        handleMessageRefresh();
7814fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        break;
7824fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
7834fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
784edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
7854fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageTransaction() {
786e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    uint32_t transactionFlags = peekTransactionFlags(eTransactionMask);
7874fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    if (transactionFlags) {
78887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        handleTransaction(transactionFlags);
7894fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
7904fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
791edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
7924fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageInvalidate() {
793cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    ATRACE_CALL();
79487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    handlePageFlip();
7954fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
7963a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian
7974fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageRefresh() {
798cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    ATRACE_CALL();
799cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    preComposition();
800cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    rebuildLayerStacks();
801cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    setUpHWComposer();
802cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    doDebugFlashRegions();
803cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    doComposition();
804cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    postComposition();
805cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
806cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
807cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doDebugFlashRegions()
808cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{
809cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    // is debugging enabled
810cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (CC_LIKELY(!mDebugRegion))
811cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        return;
812cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
813cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    const bool repaintEverything = mRepaintEverything;
814cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
815cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
816cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        if (hw->canDraw()) {
817cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            // transform the dirty region into this screen's coordinate space
818cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            const Region dirtyRegion(hw->getDirtyRegion(repaintEverything));
819cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            if (!dirtyRegion.isEmpty()) {
820cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                // redraw the whole screen
821cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                doComposeSurfaces(hw, Region(hw->bounds()));
822cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
823cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                // and draw the dirty region
824cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                glDisable(GL_TEXTURE_EXTERNAL_OES);
825cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                glDisable(GL_TEXTURE_2D);
826cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                glDisable(GL_BLEND);
827cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                glColor4f(1, 0, 1, 1);
828cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                const int32_t height = hw->getHeight();
829cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                Region::const_iterator it = dirtyRegion.begin();
830cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                Region::const_iterator const end = dirtyRegion.end();
831cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                while (it != end) {
832cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                    const Rect& r = *it++;
833cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                    GLfloat vertices[][2] = {
834cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            { r.left,  height - r.top },
835cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            { r.left,  height - r.bottom },
836cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            { r.right, height - r.bottom },
837cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            { r.right, height - r.top }
838cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                    };
839cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                    glVertexPointer(2, GL_FLOAT, 0, vertices);
840cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
841cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                }
842cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                hw->compositionComplete();
843da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                hw->swapBuffers(getHwComposer());
844cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            }
845cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        }
846cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
847cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
848cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    postFramebuffer();
849cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
850cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (mDebugRegion > 1) {
851cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        usleep(mDebugRegion * 1000);
852cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
853bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian
854bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian    HWComposer& hwc(getHwComposer());
855bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian    if (hwc.initCheck() == NO_ERROR) {
856bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian        status_t err = hwc.prepare();
857bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian        ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
858bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian    }
859cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
860cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
861cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::preComposition()
862cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{
863cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    bool needExtraInvalidate = false;
864cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
865cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    const size_t count = currentLayers.size();
866cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    for (size_t i=0 ; i<count ; i++) {
867cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        if (currentLayers[i]->onPreComposition()) {
868cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            needExtraInvalidate = true;
869cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        }
870cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
871cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (needExtraInvalidate) {
872cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        signalLayerUpdate();
873cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
874cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
875a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
876cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::postComposition()
877cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{
878cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
879cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    const size_t count = currentLayers.size();
880cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    for (size_t i=0 ; i<count ; i++) {
881cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        currentLayers[i]->onPostComposition();
882cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
883cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
884cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
885cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::rebuildLayerStacks() {
886cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    // rebuild the visible layer list per screen
88752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    if (CC_UNLIKELY(mVisibleRegionsDirty)) {
888cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        ATRACE_CALL();
88987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        mVisibleRegionsDirty = false;
89087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        invalidateHwcGeometry();
891ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian
89287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
89392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
894ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian            Region opaqueRegion;
895ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian            Region dirtyRegion;
896ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian            Vector< sp<LayerBase> > layersSortedByZ;
8974297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            const sp<DisplayDevice>& hw(mDisplays[dpy]);
8987e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian            const Transform& tr(hw->getTransform());
8997e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian            const Rect bounds(hw->getBounds());
900ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian            if (hw->canDraw()) {
901ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                SurfaceFlinger::computeVisibleRegions(currentLayers,
902ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                        hw->getLayerStack(), dirtyRegion, opaqueRegion);
9037e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian
904ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                const size_t count = currentLayers.size();
905ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                for (size_t i=0 ; i<count ; i++) {
906ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                    const sp<LayerBase>& layer(currentLayers[i]);
907ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                    const Layer::State& s(layer->drawingState());
908ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                    if (s.layerStack == hw->getLayerStack()) {
909a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                        Region drawRegion(tr.transform(
910a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                                layer->visibleNonTransparentRegion));
911a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                        drawRegion.andSelf(bounds);
912a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                        if (!drawRegion.isEmpty()) {
913ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                            layersSortedByZ.add(layer);
914ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                        }
91587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian                    }
91687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian                }
9173b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian            }
9184297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->setVisibleLayersSortedByZ(layersSortedByZ);
9197e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian            hw->undefinedRegion.set(bounds);
9207e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian            hw->undefinedRegion.subtractSelf(tr.transform(opaqueRegion));
9217e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian            hw->dirtyRegion.orSelf(dirtyRegion);
9223b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        }
9233b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
924cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
9253b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
926cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::setUpHWComposer() {
92752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    HWComposer& hwc(getHwComposer());
92852bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    if (hwc.initCheck() == NO_ERROR) {
92952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        // build the h/w work list
930a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis        if (CC_UNLIKELY(mHwWorkListDirty)) {
931a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis            mHwWorkListDirty = false;
932a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis            for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
933a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                sp<const DisplayDevice> hw(mDisplays[dpy]);
934a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                const int32_t id = hw->getHwcDisplayId();
935a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                if (id >= 0) {
936a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                    const Vector< sp<LayerBase> >& currentLayers(
937a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                        hw->getVisibleLayersSortedByZ());
938a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                    const size_t count = currentLayers.size();
939a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                    if (hwc.createWorkList(id, count) == NO_ERROR) {
940a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                        HWComposer::LayerListIterator cur = hwc.begin(id);
941a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                        const HWComposer::LayerListIterator end = hwc.end(id);
942a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                        for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
943a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                            const sp<LayerBase>& layer(currentLayers[i]);
944a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                            layer->setGeometry(hw, *cur);
945a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                            if (mDebugDisableHWC || mDebugRegion) {
946a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                                cur->setSkip(true);
947a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                            }
948a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                        }
949a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                    }
950a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                }
951a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis            }
952a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis        }
953a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis
954a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis        // set the per-frame data
95592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
9564297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            sp<const DisplayDevice> hw(mDisplays[dpy]);
957e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian            const int32_t id = hw->getHwcDisplayId();
958e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian            if (id >= 0) {
959e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                const Vector< sp<LayerBase> >& currentLayers(
960cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                    hw->getVisibleLayersSortedByZ());
961e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                const size_t count = currentLayers.size();
962a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                HWComposer::LayerListIterator cur = hwc.begin(id);
963a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                const HWComposer::LayerListIterator end = hwc.end(id);
964a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
965a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                    /*
966a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                     * update the per-frame h/w composer data for each layer
967a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                     * and build the transparent region of the FB
968a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                     */
969a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                    const sp<LayerBase>& layer(currentLayers[i]);
970a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                    layer->setPerFrameData(hw, *cur);
9711e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                }
97252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            }
97387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        }
974a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis
97552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        status_t err = hwc.prepare();
97652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
97752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    }
978cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
97952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian
980cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doComposition() {
981cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    ATRACE_CALL();
98252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    const bool repaintEverything = android_atomic_and(0, &mRepaintEverything);
98392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
9844297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
985cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        if (hw->canDraw()) {
986cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            // transform the dirty region into this screen's coordinate space
987cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            const Region dirtyRegion(hw->getDirtyRegion(repaintEverything));
98802b95105754b1859a97e234b79f41489a4677c20Mathias Agopian
98902b95105754b1859a97e234b79f41489a4677c20Mathias Agopian            // repaint the framebuffer (if needed)
99002b95105754b1859a97e234b79f41489a4677c20Mathias Agopian            doDisplayComposition(hw, dirtyRegion);
99102b95105754b1859a97e234b79f41489a4677c20Mathias Agopian
992cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            hw->dirtyRegion.clear();
993cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            hw->flip(hw->swapRegion);
994cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            hw->swapRegion.clear();
99587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        }
99652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        // inform the h/w that we're done compositing
9974297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        hw->compositionComplete();
9984fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
99952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    postFramebuffer();
1000edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1001edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1002edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer()
1003edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1004841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
1005b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian
1006a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    const nsecs_t now = systemTime();
1007a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = now;
1008c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall
100952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    HWComposer& hwc(getHwComposer());
1010ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall    if (hwc.initCheck() == NO_ERROR) {
10112a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian        if (!hwc.supportsFramebufferTarget()) {
10122a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian            // EGL spec says:
10132a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian            //   "surface must be bound to the calling thread's current context,
10142a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian            //    for the current rendering API."
10152a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian            DisplayDevice::makeCurrent(mEGLDisplay,
10162a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian                    getDefaultDisplayDevice(), mEGLContext);
10172a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian        }
1018e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian        hwc.commit();
101952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    }
102052bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian
102192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
10224297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        sp<const DisplayDevice> hw(mDisplays[dpy]);
10234297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const Vector< sp<LayerBase> >& currentLayers(hw->getVisibleLayersSortedByZ());
1024da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian        hw->onSwapBuffersCompleted(hwc);
102552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        const size_t count = currentLayers.size();
1026e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian        int32_t id = hw->getHwcDisplayId();
1027e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian        if (id >=0 && hwc.initCheck() == NO_ERROR) {
10281e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian            HWComposer::LayerListIterator cur = hwc.begin(id);
10291e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian            const HWComposer::LayerListIterator end = hwc.end(id);
103052bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            for (size_t i = 0; cur != end && i < count; ++i, ++cur) {
1031d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian                currentLayers[i]->onLayerDisplayed(hw, &*cur);
103252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            }
1033cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        } else {
103452bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            for (size_t i = 0; i < count; i++) {
1035d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian                currentLayers[i]->onLayerDisplayed(hw, NULL);
103652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            }
1037ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall        }
1038e8696a40e09b24b634214684d18526187b316a2fJamie Gennis    }
1039e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
1040a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mLastSwapBufferTime = systemTime() - now;
1041a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = 0;
1042edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1043edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
104487baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
1045edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1046841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
1047841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
1048ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    Mutex::Autolock _l(mStateLock);
1049ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    const nsecs_t now = systemTime();
1050ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = now;
1051ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
1052ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // Here we're guaranteed that some transaction flags are set
1053ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // so we can call handleTransactionLocked() unconditionally.
1054ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // We call getTransactionFlags(), which will also clear the flags,
1055ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // with mStateLock held to guarantee that mCurrentState won't change
1056ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // until the transaction is committed.
1057ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
1058e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    transactionFlags = getTransactionFlags(eTransactionMask);
105987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    handleTransactionLocked(transactionFlags);
1060ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
1061ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mLastTransactionTime = systemTime() - now;
1062ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = 0;
1063ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    invalidateHwcGeometry();
1064ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // here the transaction has been committed
10653d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian}
1066edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
106787baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
10683d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{
10693d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    const LayerVector& currentLayers(mCurrentState.layersSortedByZ);
1070edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t count = currentLayers.size();
1071edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1072edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
1073edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Traversal of the children
1074edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * (perform the transaction for each of them if needed)
1075edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
1076edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
10773559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    if (transactionFlags & eTraversalNeeded) {
1078edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (size_t i=0 ; i<count ; i++) {
10798430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            const sp<LayerBase>& layer(currentLayers[i]);
1080edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
1081edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (!trFlags) continue;
1082edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1083edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const uint32_t flags = layer->doTransaction(0);
1084edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (flags & Layer::eVisibleRegion)
1085edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mVisibleRegionsDirty = true;
1086edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1087edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1088edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1089edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
10903559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian     * Perform display own transactions if needed
1091edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
1092edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1093e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    if (transactionFlags & eDisplayTransactionNeeded) {
109492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        // here we take advantage of Vector's copy-on-write semantics to
109592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        // improve performance by skipping the transaction entirely when
109692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        // know that the lists are identical
1097e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const KeyedVector<  wp<IBinder>, DisplayDeviceState>& curr(mCurrentState.displays);
1098e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const KeyedVector<  wp<IBinder>, DisplayDeviceState>& draw(mDrawingState.displays);
109992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        if (!curr.isIdenticalTo(draw)) {
1100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
110192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            const size_t cc = curr.size();
110293997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                  size_t dc = draw.size();
110392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian
110492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // find the displays that were removed
110592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // (ie: in drawing state but not in current state)
110692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // also handle displays that changed
110792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // (ie: displays that are in both lists)
110892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            for (size_t i=0 ; i<dc ; i++) {
1109e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                const ssize_t j = curr.indexOfKey(draw.keyAt(i));
1110e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                if (j < 0) {
111192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    // in drawing state but not in current state
11123ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian                    if (!draw[i].isMainDisplay()) {
111327ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden                        // Call makeCurrent() on the primary display so we can
111427ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden                        // be sure that nothing associated with this display
111527ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden                        // is current.
1116db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian                        const sp<const DisplayDevice> hw(getDefaultDisplayDevice());
111727ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden                        DisplayDevice::makeCurrent(mEGLDisplay, hw, mEGLContext);
11183ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian                        mDisplays.removeItem(draw.keyAt(i));
111927ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden                        getHwComposer().disconnectDisplay(draw[i].type);
11209e9689c11148521d2c16a121a0b87b062be0714cAndy McFadden                        mEventThread->onHotplugReceived(draw[i].type, false);
112192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    } else {
112292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                        ALOGW("trying to remove the main display");
112392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    }
112492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                } else {
112592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    // this display is in both lists. see if something changed.
1126e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                    const DisplayDeviceState& state(curr[j]);
11273ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian                    const wp<IBinder>& display(curr.keyAt(j));
1128111b2d89221722d38f5b5b3ba65904ec22421839Mathias Agopian                    if (state.surface->asBinder() != draw[i].surface->asBinder()) {
1129e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        // changing the surface is like destroying and
113093997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // recreating the DisplayDevice, so we just remove it
113193997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // from the drawing state, so that it get re-added
113293997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // below.
113393997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        mDisplays.removeItem(display);
113493997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        mDrawingState.displays.removeItemsAt(i);
113593997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        dc--; i--;
113693997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // at this point we must loop to the next item
113793997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        continue;
113892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    }
113993997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian
1140db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian                    const sp<DisplayDevice> disp(getDisplayDevice(display));
114193997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                    if (disp != NULL) {
114293997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        if (state.layerStack != draw[i].layerStack) {
114393997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                            disp->setLayerStack(state.layerStack);
114493997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        }
114500e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                        if ((state.orientation != draw[i].orientation)
114600e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                                || (state.viewport != draw[i].viewport)
114700e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                                || (state.frame != draw[i].frame))
114800e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                        {
114900e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                            disp->setProjection(state.orientation,
11504fb3999cea652617be5125f8a42c257467bf3c77Jeff Brown                                    state.viewport, state.frame);
115193997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        }
115292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    }
115392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                }
115492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            }
115592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian
115692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // find displays that were added
115792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // (ie: in current state but not in drawing state)
115892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            for (size_t i=0 ; i<cc ; i++) {
1159e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                if (draw.indexOfKey(curr.keyAt(i)) < 0) {
1160e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                    const DisplayDeviceState& state(curr[i]);
1161cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian
1162cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                    sp<FramebufferSurface> fbs;
1163cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                    sp<SurfaceTextureClient> stc;
1164cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                    if (!state.isVirtualDisplay()) {
1165cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian
1166cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        ALOGE_IF(state.surface!=NULL,
1167cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                                "adding a supported display, but rendering "
1168cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                                "surface is provided (%p), ignoring it",
1169cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                                state.surface.get());
1170cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian
1171cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        // for supported (by hwc) displays we provide our
1172cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        // own rendering surface
1173f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian                        fbs = new FramebufferSurface(*mHwc, state.type);
1174cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        stc = new SurfaceTextureClient(
11752adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden                                static_cast< sp<IGraphicBufferProducer> >(
1176dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis                                        fbs->getBufferQueue()));
1177cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                    } else {
1178cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        if (state.surface != NULL) {
1179cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                            stc = new SurfaceTextureClient(state.surface);
1180cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        }
1181cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                    }
1182cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian
1183cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                    const wp<IBinder>& display(curr.keyAt(i));
1184cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                    if (stc != NULL) {
1185cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        sp<DisplayDevice> hw = new DisplayDevice(this,
1186692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall                                state.type, state.isSecure, display, stc, fbs,
1187dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis                                mEGLConfig);
1188cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        hw->setLayerStack(state.layerStack);
1189cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        hw->setProjection(state.orientation,
11904fb3999cea652617be5125f8a42c257467bf3c77Jeff Brown                                state.viewport, state.frame);
11918dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden                        hw->setDisplayName(state.displayName);
1192cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        mDisplays.add(display, hw);
11939e9689c11148521d2c16a121a0b87b062be0714cAndy McFadden                        mEventThread->onHotplugReceived(state.type, true);
119493997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                    }
119592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                }
119692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            }
1197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
11983559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    }
1199edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
12008430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian    if (transactionFlags & (eTraversalNeeded|eDisplayTransactionNeeded)) {
12018430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // The transform hint might have changed for some layers
12028430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // (either because a display has changed, or because a layer
12038430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // as changed).
12048430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
12058430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // Walk through all the layers in currentLayers,
12068430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // and update their transform hint.
12078430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
12088430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // If a layer is visible only on a single display, then that
12098430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // display is used to calculate the hint, otherwise we use the
12108430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // default display.
12118430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
12128430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // NOTE: we do this here, rather than in rebuildLayerStacks() so that
12138430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // the hint is set before we acquire a buffer from the surface texture.
12148430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
12158430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // NOTE: layer transactions have taken place already, so we use their
12168430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // drawing state. However, SurfaceFlinger's own transaction has not
12178430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // happened yet, so we must use the current state layer list
12188430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // (soon to become the drawing state list).
12198430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
12208430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        sp<const DisplayDevice> disp;
12218430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        uint32_t currentlayerStack = 0;
12228430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        for (size_t i=0; i<count; i++) {
12238430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            // NOTE: we rely on the fact that layers are sorted by
12248430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            // layerStack first (so we don't have to traverse the list
12258430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            // of displays for every layer).
12268430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            const sp<LayerBase>& layerBase(currentLayers[i]);
12278430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            uint32_t layerStack = layerBase->drawingState().layerStack;
12288430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            if (i==0 || currentlayerStack != layerStack) {
12298430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                currentlayerStack = layerStack;
12308430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                // figure out if this layerstack is mirrored
12318430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                // (more than one display) if so, pick the default display,
12328430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                // if not, pick the only display it's on.
12338430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                disp.clear();
12348430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
12358430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                    sp<const DisplayDevice> hw(mDisplays[dpy]);
12368430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                    if (hw->getLayerStack() == currentlayerStack) {
12378430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                        if (disp == NULL) {
12388430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                            disp = hw;
12398430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                        } else {
12408430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                            disp = getDefaultDisplayDevice();
12418430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                            break;
12428430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                        }
12438430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                    }
12448430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                }
12458430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            }
12468430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            if (disp != NULL) {
12478430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                // presumably this means this layer is using a layerStack
12488430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                // that is not visible on any display
12498430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                layerBase->updateTransformHint(disp);
12508430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            }
12518430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        }
12528430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian    }
12538430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian
12548430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian
12553559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    /*
12563559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian     * Perform our own transaction if needed
12573559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian     */
1258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1259cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    const LayerVector& previousLayers(mDrawingState.layersSortedByZ);
1260cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (currentLayers.size() > previousLayers.size()) {
12613559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        // layers have been added
12623559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        mVisibleRegionsDirty = true;
12633559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    }
12643559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian
12653559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    // some layers might have been removed, so
12663559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    // we need to update the regions they're exposing.
12673559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    if (mLayersRemoved) {
12683559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        mLayersRemoved = false;
12693559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        mVisibleRegionsDirty = true;
12703559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        const size_t count = previousLayers.size();
12713559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        for (size_t i=0 ; i<count ; i++) {
12723559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian            const sp<LayerBase>& layer(previousLayers[i]);
12733559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian            if (currentLayers.indexOf(layer) < 0) {
12743559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                // this layer is not visible anymore
12753559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                // TODO: we could traverse the tree from front to back and
12763559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                //       compute the actual visible region
12773559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                // TODO: we could cache the transformed region
12781501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian                const Layer::State& s(layer->drawingState());
12791501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian                Region visibleReg = s.transform.transform(
12801501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian                        Region(Rect(s.active.w, s.active.h)));
12811501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian                invalidateLayerStack(s.layerStack, visibleReg);
12820aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            }
1283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1284edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1285edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1286edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    commitTransaction();
12874fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
12884fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
12894fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::commitTransaction()
12904fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian{
12914fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    if (!mLayersPendingRemoval.isEmpty()) {
12924fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // Notify removed layers now that they can't be drawn from
12934fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        for (size_t i = 0; i < mLayersPendingRemoval.size(); i++) {
12944fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            mLayersPendingRemoval[i]->onRemoved();
12954fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        }
12964fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        mLayersPendingRemoval.clear();
12974fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
12984fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
12994fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mDrawingState = mCurrentState;
13002d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis    mTransactionPending = false;
13012d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis    mAnimTransactionPending = false;
13024fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mTransactionCV.broadcast();
1303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::computeVisibleRegions(
130687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const LayerVector& currentLayers, uint32_t layerStack,
130787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        Region& outDirtyRegion, Region& outOpaqueRegion)
1308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1309841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
1310841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
1311edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveOpaqueLayers;
1312edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveCoveredLayers;
1313edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region dirty;
1314edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
131587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    outDirtyRegion.clear();
1316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t i = currentLayers.size();
1318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    while (i--) {
1319076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        const sp<LayerBase>& layer = currentLayers[i];
1320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // start with the whole surface at its current location
1322970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian        const Layer::State& s(layer->drawingState());
1323edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
132487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        // only consider the layers on the given later stack
132587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        if (s.layerStack != layerStack)
132687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            continue;
132787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
1328ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
1329ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * opaqueRegion: area of a surface that is fully opaque.
1330ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
1331edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region opaqueRegion;
1332ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1333ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
1334ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visibleRegion: area of a surface that is visible on screen
1335ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * and not fully transparent. This is essentially the layer's
1336ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * footprint minus the opaque regions above it.
1337ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * Areas covered by a translucent surface are considered visible.
1338ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
1339edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region visibleRegion;
1340ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1341ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
1342ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * coveredRegion: area of a surface that is covered by all
1343ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visible regions above it (which includes the translucent areas).
1344ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
1345edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region coveredRegion;
1346ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1347a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall        /*
1348a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * transparentRegion: area of a surface that is hinted to be completely
1349a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * transparent. This is only used to tell when the layer has no visible
1350a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * non-transparent regions and can be removed from the layer list. It
1351a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * does not affect the visibleRegion of this layer or any layers
1352a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * beneath it. The hint may not be correct if apps don't respect the
1353a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * SurfaceView restrictions (which, sadly, some don't).
1354a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         */
1355a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall        Region transparentRegion;
1356a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall
1357ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1358ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // handle hidden surfaces by setting the visible region to empty
1359da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian        if (CC_LIKELY(layer->isVisible())) {
1360a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            const bool translucent = !layer->isOpaque();
13614fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            Rect bounds(layer->computeBounds());
1362edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            visibleRegion.set(bounds);
1363ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            if (!visibleRegion.isEmpty()) {
1364ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // Remove the transparent area from the visible region
1365ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (translucent) {
13664fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    const Transform tr(s.transform);
13674fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    if (tr.transformed()) {
13684fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                        if (tr.preserveRects()) {
13694fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            // transform the transparent region
1370a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                            transparentRegion = tr.transform(s.transparentRegion);
13714fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                        } else {
13724fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            // transformation too complex, can't do the
13734fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            // transparent region optimization.
1374a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                            transparentRegion.clear();
13754fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                        }
13764fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    } else {
1377a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                        transparentRegion = s.transparentRegion;
13784fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    }
1379ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
1380edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1381ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // compute the opaque region
13824fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                const int32_t layerOrientation = s.transform.getOrientation();
1383ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (s.alpha==255 && !translucent &&
1384ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                        ((layerOrientation & Transform::ROT_INVALID) == false)) {
1385ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    // the opaque region is the layer's footprint
1386ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    opaqueRegion = visibleRegion;
1387ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
1388edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1389edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1390edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1391ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Clip the covered region to the visible region
1392ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        coveredRegion = aboveCoveredLayers.intersect(visibleRegion);
1393ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1394ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveCoveredLayers for next (lower) layer
1395ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        aboveCoveredLayers.orSelf(visibleRegion);
1396ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1397edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // subtract the opaque region covered by the layers above us
1398edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        visibleRegion.subtractSelf(aboveOpaqueLayers);
1399edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1400edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // compute this layer's dirty region
1401edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (layer->contentDirty) {
1402edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // we need to invalidate the whole region
1403edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dirty = visibleRegion;
1404edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // as well, as the old visible region
14054fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            dirty.orSelf(layer->visibleRegion);
1406edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->contentDirty = false;
1407edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
1408a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian            /* compute the exposed region:
1409ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   the exposed region consists of two components:
1410ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   1) what's VISIBLE now and was COVERED before
1411ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   2) what's EXPOSED now less what was EXPOSED before
1412ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
1413ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * note that (1) is conservative, we start with the whole
1414ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * visible region but only keep what used to be covered by
1415ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * something -- which mean it may have been exposed.
1416ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
1417ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * (2) handles areas that were not covered by anything but got
1418ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * exposed because of a resize.
1419a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian             */
1420ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region newExposed = visibleRegion - coveredRegion;
14214fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region oldVisibleRegion = layer->visibleRegion;
14224fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region oldCoveredRegion = layer->coveredRegion;
1423ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldExposed = oldVisibleRegion - oldCoveredRegion;
1424ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed);
1425edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1426edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirty.subtractSelf(aboveOpaqueLayers);
1427edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1428edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // accumulate to the screen dirty region
142987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        outDirtyRegion.orSelf(dirty);
1430edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1431ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveOpaqueLayers for next (lower) layer
1432edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        aboveOpaqueLayers.orSelf(opaqueRegion);
14338b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
1434a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall        // Store the visible region in screen space
1435edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setVisibleRegion(visibleRegion);
1436edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setCoveredRegion(coveredRegion);
1437a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall        layer->setVisibleNonTransparentRegion(
1438a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                visibleRegion.subtract(transparentRegion));
1439edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1440edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
144187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    outOpaqueRegion = aboveOpaqueLayers;
1442edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1443edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
144487baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::invalidateLayerStack(uint32_t layerStack,
144587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const Region& dirty) {
144692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
14474297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
14484297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        if (hw->getLayerStack() == layerStack) {
14494297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->dirtyRegion.orSelf(dirty);
145092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        }
145192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    }
145287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian}
145387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
145487baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handlePageFlip()
1455edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
14564fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    Region dirtyRegion;
145799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
14584fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    bool visibleRegions = false;
1459cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
14604fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    const size_t count = currentLayers.size();
14614fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    for (size_t i=0 ; i<count ; i++) {
1462cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
146387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const Region dirty(layer->latchBuffer(visibleRegions));
14641501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian        const Layer::State& s(layer->drawingState());
146587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        invalidateLayerStack(s.layerStack, dirty);
14664fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
14674da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
14683b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    mVisibleRegionsDirty |= visibleRegions;
1469edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1470edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1471ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopianvoid SurfaceFlinger::invalidateHwcGeometry()
1472ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian{
1473ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian    mHwWorkListDirty = true;
1474ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian}
1475ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian
147699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
1477cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doDisplayComposition(const sp<const DisplayDevice>& hw,
147887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const Region& inDirtyRegion)
1479edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
148087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    Region dirtyRegion(inDirtyRegion);
148187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
1482b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // compute the invalid region
14834297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->swapRegion.orSelf(dirtyRegion);
1484edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
14854297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    uint32_t flags = hw->getFlags();
14860f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian    if (flags & DisplayDevice::SWAP_RECTANGLE) {
148729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // we can redraw only what's dirty, but since SWAP_RECTANGLE only
148829d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // takes a rectangle, we must make sure to update that whole
148929d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // rectangle in that case
14904297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        dirtyRegion.set(hw->swapRegion.bounds());
1491edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
14920f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian        if (flags & DisplayDevice::PARTIAL_UPDATES) {
149329d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // We need to redraw the rectangle that will be updated
1494df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian            // (pushed to the framebuffer).
149595a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian            // This is needed because PARTIAL_UPDATES only takes one
14960f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian            // rectangle instead of a region (see DisplayDevice::flip())
14974297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            dirtyRegion.set(hw->swapRegion.bounds());
1498edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
149929d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // we need to redraw everything (the whole screen)
15004297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            dirtyRegion.set(hw->bounds());
15014297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->swapRegion = dirtyRegion;
1502edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1503edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1504edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1505cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    doComposeSurfaces(hw, dirtyRegion);
1506edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
15079c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    // update the swap region and clear the dirty region
15084297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->swapRegion.orSelf(dirtyRegion);
1509da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
1510da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian    // swap buffers (presentation)
1511da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian    hw->swapBuffers(getHwComposer());
1512edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1513edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1514cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& hw, const Region& dirty)
1515edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
151685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    const int32_t id = hw->getHwcDisplayId();
15178630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    HWComposer& hwc(getHwComposer());
15181e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian    HWComposer::LayerListIterator cur = hwc.begin(id);
15191e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian    const HWComposer::LayerListIterator end = hwc.end(id);
1520a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
152185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    const bool hasGlesComposition = hwc.hasGlesComposition(id) || (cur==end);
152285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    if (hasGlesComposition) {
1523da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian        DisplayDevice::makeCurrent(mEGLDisplay, hw, mEGLContext);
1524a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
152552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        // set the frame buffer
152652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        glMatrixMode(GL_MODELVIEW);
152752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        glLoadIdentity();
1528a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
1529a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        // Never touch the framebuffer if we don't have any framebuffer layers
153085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        const bool hasHwcComposition = hwc.hasHwcComposition(id);
1531e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian        if (hasHwcComposition) {
1532b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // when using overlays, we assume a fully transparent framebuffer
1533b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // NOTE: we could reduce how much we need to clear, for instance
1534b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // remove where there are opaque FB layers. however, on some
1535b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // GPUs doing a "clean slate" glClear might be more efficient.
1536b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // We'll revisit later if needed.
1537b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            glClearColor(0, 0, 0, 0);
1538b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            glClear(GL_COLOR_BUFFER_BIT);
1539b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian        } else {
1540766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // we start with the whole screen area
1541766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            const Region bounds(hw->getBounds());
1542766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian
1543766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // we remove the scissor part
1544766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // we're left with the letterbox region
1545766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // (common case is that letterbox ends-up being empty)
1546766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            const Region letterbox(bounds.subtract(hw->getScissor()));
1547766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian
1548766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // compute the area to clear
1549766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            Region region(hw->undefinedRegion.merge(letterbox));
1550766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian
1551766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // but limit it to the dirty region
1552766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            region.andSelf(dirty);
1553766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian
1554b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // screen is already cleared here
155587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            if (!region.isEmpty()) {
1556b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                // can happen with SurfaceView
155755801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian                drawWormhole(hw, region);
1558b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            }
1559a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        }
1560f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian
1561766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian        if (hw->getDisplayType() != DisplayDevice::DISPLAY_PRIMARY) {
1562766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // just to be on the safe side, we don't set the
1563f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian            // scissor on the main display. It should never be needed
1564f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian            // anyways (though in theory it could since the API allows it).
1565f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian            const Rect& bounds(hw->getBounds());
1566766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            const Rect& scissor(hw->getScissor());
1567f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian            if (scissor != bounds) {
1568f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian                // scissor doesn't match the screen's dimensions, so we
1569f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian                // need to clear everything outside of it and enable
1570f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian                // the GL scissor so we don't draw anything where we shouldn't
1571f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian                const GLint height = hw->getHeight();
1572f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian                glScissor(scissor.left, height - scissor.bottom,
1573f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian                        scissor.getWidth(), scissor.getHeight());
1574f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian                // enable scissor for this frame
1575f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian                glEnable(GL_SCISSOR_TEST);
1576f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian            }
1577f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian        }
157885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    }
15794b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian
158085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    /*
158185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian     * and then, render the layers targeted at the framebuffer
158285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian     */
15834b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian
158485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    const Vector< sp<LayerBase> >& layers(hw->getVisibleLayersSortedByZ());
158585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    const size_t count = layers.size();
158685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    const Transform& tr = hw->getTransform();
158785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    if (cur != end) {
158885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        // we're using h/w composer
158985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        for (size_t i=0 ; i<count && cur!=end ; ++i, ++cur) {
1590a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian            const sp<LayerBase>& layer(layers[i]);
15914fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region clip(dirty.intersect(tr.transform(layer->visibleRegion)));
159285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            if (!clip.isEmpty()) {
159385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                switch (cur->getCompositionType()) {
159485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                    case HWC_OVERLAY: {
159585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                        if ((cur->getHints() & HWC_HINT_CLEAR_FB)
159685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                                && i
159785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                                && layer->isOpaque()
159885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                                && hasGlesComposition) {
1599cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            // never clear the very first layer since we're
1600cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            // guaranteed the FB is already cleared
1601cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            layer->clearWithOpenGL(hw, clip);
1602cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                        }
160385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                        break;
160485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                    }
160585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                    case HWC_FRAMEBUFFER: {
1606cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                        layer->draw(hw, clip);
160785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                        break;
1608a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                    }
1609da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                    case HWC_FRAMEBUFFER_TARGET: {
1610da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                        // this should not happen as the iterator shouldn't
1611da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                        // let us get there.
1612da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                        ALOGW("HWC_FRAMEBUFFER_TARGET found in hwc list (index=%d)", i);
1613da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                        break;
1614da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                    }
1615cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                }
1616a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall            }
161785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            layer->setAcquireFence(hw, *cur);
161885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        }
161985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    } else {
162085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        // we're not using h/w composer
162185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        for (size_t i=0 ; i<count ; ++i) {
162285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            const sp<LayerBase>& layer(layers[i]);
162385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            const Region clip(dirty.intersect(
162485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                    tr.transform(layer->visibleRegion)));
162585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            if (!clip.isEmpty()) {
162685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                layer->draw(hw, clip);
162785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            }
16284b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian        }
16294b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian    }
1630f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian
1631f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian    // disable scissor at the end of the frame
1632f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian    glDisable(GL_SCISSOR_TEST);
1633edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1634edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
163555801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopianvoid SurfaceFlinger::drawWormhole(const sp<const DisplayDevice>& hw,
163655801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian        const Region& region) const
1637edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1638f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    glDisable(GL_TEXTURE_EXTERNAL_OES);
1639b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian    glDisable(GL_TEXTURE_2D);
1640f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    glDisable(GL_BLEND);
1641b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian    glColor4f(0,0,0,0);
1642f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian
164355801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian    const int32_t height = hw->getHeight();
1644f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    Region::const_iterator it = region.begin();
1645f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    Region::const_iterator const end = region.end();
1646f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    while (it != end) {
1647f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        const Rect& r = *it++;
164855801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian        GLfloat vertices[][2] = {
164955801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian                { r.left,  height - r.top },
165055801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian                { r.left,  height - r.bottom },
165155801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian                { r.right, height - r.bottom },
165255801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian                { r.right, height - r.top }
165355801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian        };
165455801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian        glVertexPointer(2, GL_FLOAT, 0, vertices);
1655f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1656f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    }
1657edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1658edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
165996f0819f81293076e652792794a961543e6750d7Mathias Agopianssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
166096f0819f81293076e652792794a961543e6750d7Mathias Agopian        const sp<LayerBaseClient>& lbc)
16611b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
166296f0819f81293076e652792794a961543e6750d7Mathias Agopian    // attach this layer to the client
16634f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    size_t name = client->attachLayer(lbc);
16644f113740180b6512b43723c4728f262882dc9b45Mathias Agopian
166596f0819f81293076e652792794a961543e6750d7Mathias Agopian    // add this layer to the current state list
1666921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    Mutex::Autolock _l(mStateLock);
1667921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    mCurrentState.layersSortedByZ.add(lbc);
166896f0819f81293076e652792794a961543e6750d7Mathias Agopian
16694f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    return ssize_t(name);
167096f0819f81293076e652792794a961543e6750d7Mathias Agopian}
167196f0819f81293076e652792794a961543e6750d7Mathias Agopian
167296f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer)
167396f0819f81293076e652792794a961543e6750d7Mathias Agopian{
167496f0819f81293076e652792794a961543e6750d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
167596f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = purgatorizeLayer_l(layer);
167696f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR)
16773559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        setTransactionFlags(eTransactionNeeded);
167896f0819f81293076e652792794a961543e6750d7Mathias Agopian    return err;
1679edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1680edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1681076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase)
1682edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1683edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase);
1684edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (index >= 0) {
1685076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved = true;
1686edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
1687edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
16883d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    return status_t(index);
1689edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1690edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
16919a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase)
16929a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
169376cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    // First add the layer to the purgatory list, which makes sure it won't
169476cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    // go away, then remove it from the main list (through a transaction).
16959a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    ssize_t err = removeLayer_l(layerBase);
169676cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    if (err >= 0) {
169776cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian        mLayerPurgatory.add(layerBase);
169876cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    }
16998c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian
17002f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall    mLayersPendingRemoval.push(layerBase);
17010b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian
17023d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // it's possible that we don't find a layer, because it might
17033d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // have been destroyed already -- this is not technically an error
170496f0819f81293076e652792794a961543e6750d7Mathias Agopian    // from the user because there is a race between Client::destroySurface(),
170596f0819f81293076e652792794a961543e6750d7Mathias Agopian    // ~Client() and ~ISurface().
17069a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err;
17079a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
17089a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
1709dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopianuint32_t SurfaceFlinger::peekTransactionFlags(uint32_t flags)
1710dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian{
1711dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian    return android_atomic_release_load(&mTransactionFlags);
1712dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian}
1713dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian
1714edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags)
1715edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1716edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return android_atomic_and(~flags, &mTransactionFlags) & flags;
1717edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1718edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1719bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags)
1720edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1721edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t old = android_atomic_or(flags, &mTransactionFlags);
1722edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((old & flags)==0) { // wake the server up
172399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        signalTransaction();
1724edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1725edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return old;
1726edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1727edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
17288b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopianvoid SurfaceFlinger::setTransactionState(
17298b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        const Vector<ComposerState>& state,
17308b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        const Vector<DisplayState>& displays,
17318b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        uint32_t flags)
17328b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian{
17337c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis    ATRACE_CALL();
1734698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
173528378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    uint32_t transactionFlags = 0;
1736e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
17372d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis    if (flags & eAnimation) {
17382d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        // For window updates that are part of an animation we must wait for
17392d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        // previous animation "frames" to be handled.
17402d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        while (mAnimTransactionPending) {
17417c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
17422d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis            if (CC_UNLIKELY(err != NO_ERROR)) {
17432d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                // just in case something goes wrong in SF, return to the
17447c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis                // caller after a few seconds.
17457c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis                ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out "
17467c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis                        "waiting for previous animation frame");
17472d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                mAnimTransactionPending = false;
17482d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                break;
17492d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis            }
17502d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        }
17512d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis    }
17522d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis
1753e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    size_t count = displays.size();
1754e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
1755e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const DisplayState& s(displays[i]);
1756e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        transactionFlags |= setDisplayStateLocked(s);
1757b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis    }
1758b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis
1759e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    count = state.size();
1760698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
1761698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const ComposerState& s(state[i]);
1762d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // Here we need to check that the interface we're given is indeed
1763d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // one of our own. A malicious client could give us a NULL
1764d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // IInterface, or one of its own or even one of our own but a
1765d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // different type. All these situations would cause us to crash.
1766d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        //
1767d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // NOTE: it would be better to use RTTI as we could directly check
1768d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // that we have a Client*. however, RTTI is disabled in Android.
1769d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        if (s.client != NULL) {
1770d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian            sp<IBinder> binder = s.client->asBinder();
1771d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian            if (binder != NULL) {
1772d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                String16 desc(binder->getInterfaceDescriptor());
1773d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                if (desc == ISurfaceComposerClient::descriptor) {
1774d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                    sp<Client> client( static_cast<Client *>(s.client.get()) );
1775d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                    transactionFlags |= setClientStateLocked(client, s.state);
1776d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                }
1777d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian            }
1778d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        }
1779698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    }
1780386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian
178128378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    if (transactionFlags) {
1782386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // this triggers the transaction
178328378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        setTransactionFlags(transactionFlags);
1784698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian
1785386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // if this is a synchronous transaction, wait for it to take effect
1786386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // before returning.
1787386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        if (flags & eSynchronous) {
17882d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis            mTransactionPending = true;
17892d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        }
17902d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        if (flags & eAnimation) {
17912d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis            mAnimTransactionPending = true;
1792386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        }
17932d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        while (mTransactionPending) {
1794386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
1795386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            if (CC_UNLIKELY(err != NO_ERROR)) {
1796386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                // just in case something goes wrong in SF, return to the
1797386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                // called after a few seconds.
17982d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out!");
17992d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                mTransactionPending = false;
1800386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                break;
1801386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            }
1802cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        }
1803edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1804edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1805edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1806e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setDisplayStateLocked(const DisplayState& s)
1807e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{
18089a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall    ssize_t dpyIdx = mCurrentState.displays.indexOfKey(s.token);
18099a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall    if (dpyIdx < 0)
18109a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall        return 0;
18119a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall
1812e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    uint32_t flags = 0;
18139a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall    DisplayDeviceState& disp(mCurrentState.displays.editValueAt(dpyIdx));
18143ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    if (disp.isValid()) {
1815e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const uint32_t what = s.what;
1816e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & DisplayState::eSurfaceChanged) {
1817e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.surface->asBinder() != s.surface->asBinder()) {
1818e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.surface = s.surface;
1819e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
1820e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1821e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1822e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & DisplayState::eLayerStackChanged) {
1823e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.layerStack != s.layerStack) {
1824e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.layerStack = s.layerStack;
1825e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
1826e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1827e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
182800e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian        if (what & DisplayState::eDisplayProjectionChanged) {
1829e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.orientation != s.orientation) {
1830e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.orientation = s.orientation;
1831e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
1832e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1833e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.frame != s.frame) {
1834e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.frame = s.frame;
1835e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
1836e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1837e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.viewport != s.viewport) {
1838e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.viewport = s.viewport;
1839e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
1840e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1841e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1842e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
1843e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return flags;
1844e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
1845e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
1846e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setClientStateLocked(
1847e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const sp<Client>& client,
1848e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const layer_state_t& s)
1849e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{
1850e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    uint32_t flags = 0;
1851e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    sp<LayerBaseClient> layer(client->getLayerUser(s.surface));
1852e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    if (layer != 0) {
1853e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const uint32_t what = s.what;
1854e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::ePositionChanged) {
1855e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setPosition(s.x, s.y))
1856e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1857e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1858e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eLayerChanged) {
1859e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            // NOTE: index needs to be calculated before we update the state
1860e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
1861e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setLayer(s.z)) {
1862e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.removeAt(idx);
1863e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.add(layer);
1864e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // we need traversal (state changed)
1865e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // AND transaction (list changed)
1866e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTransactionNeeded|eTraversalNeeded;
1867e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1868e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1869e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eSizeChanged) {
1870e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setSize(s.w, s.h)) {
1871e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1872e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1873e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1874e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eAlphaChanged) {
1875e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f)))
1876e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1877e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1878e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eMatrixChanged) {
1879e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setMatrix(s.matrix))
1880e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1881e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1882e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eTransparentRegionChanged) {
1883e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setTransparentRegionHint(s.transparentRegion))
1884e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1885e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1886e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eVisibilityChanged) {
1887e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setFlags(s.flags, s.mask))
1888e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1889e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1890e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eCropChanged) {
1891e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setCrop(s.crop))
1892e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1893e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1894e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eLayerStackChanged) {
1895e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            // NOTE: index needs to be calculated before we update the state
1896e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
1897e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setLayerStack(s.layerStack)) {
1898e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.removeAt(idx);
1899e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.add(layer);
1900e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // we need traversal (state changed)
1901e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // AND transaction (list changed)
1902e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTransactionNeeded|eTraversalNeeded;
1903e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1904e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1905e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
1906e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return flags;
1907e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
1908e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
1909921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopiansp<ISurface> SurfaceFlinger::createLayer(
19100ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        ISurfaceComposerClient::surface_data_t* params,
19110ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const String8& name,
19120ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const sp<Client>& client,
19133ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian       uint32_t w, uint32_t h, PixelFormat format,
1914edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t flags)
1915edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1916076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBaseClient> layer;
1917a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    sp<ISurface> surfaceHandle;
19186e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian
19196e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    if (int32_t(w|h) < 0) {
1920921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        ALOGE("createLayer() failed, w or h is negative (w=%d, h=%d)",
19216e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian                int(w), int(h));
19226e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian        return surfaceHandle;
19236e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    }
19248b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
1925921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    //ALOGD("createLayer for (%d x %d), name=%s", w, h, name.string());
19263165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian    switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {
19273165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        case ISurfaceComposerClient::eFXSurfaceNormal:
19283ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian            layer = createNormalLayer(client, w, h, flags, format);
1929edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
19303165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        case ISurfaceComposerClient::eFXSurfaceBlur:
19313165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        case ISurfaceComposerClient::eFXSurfaceDim:
19323ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian            layer = createDimLayer(client, w, h, flags);
1933edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
19343165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        case ISurfaceComposerClient::eFXSurfaceScreenshot:
19353ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian            layer = createScreenshotLayer(client, w, h, flags);
1936118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian            break;
1937edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1938edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1939076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (layer != 0) {
194096f0819f81293076e652792794a961543e6750d7Mathias Agopian        layer->initStates(w, h, flags);
1941285dbde2e0cd0057be070ded3be8f5f453147edcMathias Agopian        layer->setName(name);
194296f0819f81293076e652792794a961543e6750d7Mathias Agopian        ssize_t token = addClientLayer(client, layer);
1943edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        surfaceHandle = layer->getSurface();
19448b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber        if (surfaceHandle != 0) {
194596f0819f81293076e652792794a961543e6750d7Mathias Agopian            params->token = token;
1946a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            params->identity = layer->getIdentity();
19471c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        }
194896f0819f81293076e652792794a961543e6750d7Mathias Agopian        setTransactionFlags(eTransactionNeeded);
1949edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1950edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1951edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return surfaceHandle;
1952edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1953edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1954921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopiansp<Layer> SurfaceFlinger::createNormalLayer(
19553ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian        const sp<Client>& client,
195696f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags,
19571c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        PixelFormat& format)
1958edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1959edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize the surfaces
196092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    switch (format) {
1961edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSPARENT:
1962edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSLUCENT:
1963edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        format = PIXEL_FORMAT_RGBA_8888;
1964edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1965edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_OPAQUE:
1966a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888
1967a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian        format = PIXEL_FORMAT_RGB_565;
1968a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#else
19698f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian        format = PIXEL_FORMAT_RGBX_8888;
1970a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif
1971edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1972edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1973edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1974a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888
1975a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian    if (format == PIXEL_FORMAT_RGBX_8888)
1976a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian        format = PIXEL_FORMAT_RGBA_8888;
1977a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif
1978a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian
19793ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    sp<Layer> layer = new Layer(this, client);
1980f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian    status_t err = layer->setBuffers(w, h, format, flags);
198199ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten    if (CC_LIKELY(err != NO_ERROR)) {
1982921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        ALOGE("createNormalLayer() failed (%s)", strerror(-err));
1983076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        layer.clear();
1984edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1985edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1986edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1987edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1988921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopiansp<LayerDim> SurfaceFlinger::createDimLayer(
19893ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian        const sp<Client>& client,
199096f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags)
1991edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
19923ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    sp<LayerDim> layer = new LayerDim(this, client);
1993118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    return layer;
1994118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
1995118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
1996921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopiansp<LayerScreenshot> SurfaceFlinger::createScreenshotLayer(
19973ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian        const sp<Client>& client,
1998118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags)
1999118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{
20003ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    sp<LayerScreenshot> layer = new LayerScreenshot(this, client);
2001edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
2002edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2003edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2004921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianstatus_t SurfaceFlinger::onLayerRemoved(const sp<Client>& client, SurfaceID sid)
20059a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
20069a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    /*
20079a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     * called by the window manager, when a surface should be marked for
20089a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     * destruction.
20098b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber     *
20100aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * The surface is removed from the current and drawing lists, but placed
20110aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * in the purgatory queue, so it's not destroyed right-away (we need
20120aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * to wait for all client's references to go away first).
20139a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     */
20149a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
201548d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    status_t err = NAME_NOT_FOUND;
20160aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian    Mutex::Autolock _l(mStateLock);
201796f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<LayerBaseClient> layer = client->getLayerUser(sid);
2018b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam
201948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    if (layer != 0) {
202048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        err = purgatorizeLayer_l(layer);
202148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        if (err == NO_ERROR) {
202213233e067b8f71adc3a0ade5f442265e1f27084bMathias Agopian            setTransactionFlags(eTransactionNeeded);
202348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        }
20249a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    }
20259a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return err;
20269a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
20279a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
2028921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianstatus_t SurfaceFlinger::onLayerDestroyed(const wp<LayerBaseClient>& layer)
2029edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2030759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian    // called by ~ISurface() when all references are gone
2031ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    status_t err = NO_ERROR;
2032ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    sp<LayerBaseClient> l(layer.promote());
2033ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    if (l != NULL) {
2034ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        Mutex::Autolock _l(mStateLock);
2035ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        err = removeLayer_l(l);
2036ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        if (err == NAME_NOT_FOUND) {
2037ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // The surface wasn't in the current list, which means it was
2038ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // removed already, which means it is in the purgatory,
2039ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // and need to be removed from there.
2040ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            ssize_t idx = mLayerPurgatory.remove(l);
2041e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block            ALOGE_IF(idx < 0,
2042ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian                    "layer=%p is not in the purgatory list", l.get());
2043f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        }
2044e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE_IF(err<0 && err != NAME_NOT_FOUND,
2045ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian                "error removing layer=%p (%s)", l.get(), strerror(-err));
2046ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    }
2047ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    return err;
2048edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2049edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2050b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// ---------------------------------------------------------------------------
2051b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
205213a082e160c2d1d8006b93a555a57035213d568bAndy McFaddenvoid SurfaceFlinger::onInitializeDisplays() {
205313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    // reset screen orientation
205413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    Vector<ComposerState> state;
205513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    Vector<DisplayState> displays;
205613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    DisplayState d;
205700e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian    d.what = DisplayState::eDisplayProjectionChanged;
2058692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    d.token = mBuiltinDisplays[DisplayDevice::DISPLAY_PRIMARY];
205913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    d.orientation = DisplayState::eOrientationDefault;
20604c05dd175ee3bd5119eecf368742b6510a8cfa6cJeff Brown    d.frame.makeInvalid();
20614c05dd175ee3bd5119eecf368742b6510a8cfa6cJeff Brown    d.viewport.makeInvalid();
206213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    displays.add(d);
206313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    setTransactionState(state, displays, 0);
2064cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian    onScreenAcquired(getDefaultDisplayDevice());
206513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden}
206613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
206713a082e160c2d1d8006b93a555a57035213d568bAndy McFaddenvoid SurfaceFlinger::initializeDisplays() {
206813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    class MessageScreenInitialized : public MessageBase {
206913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden        SurfaceFlinger* flinger;
207013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    public:
207113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden        MessageScreenInitialized(SurfaceFlinger* flinger) : flinger(flinger) { }
207213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden        virtual bool handler() {
207313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden            flinger->onInitializeDisplays();
207413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden            return true;
207513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden        }
207613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    };
207713a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    sp<MessageBase> msg = new MessageScreenInitialized(this);
207813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    postMessageAsync(msg);  // we may be called from main thread, use async message
207913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden}
208013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
208113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
2082cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopianvoid SurfaceFlinger::onScreenAcquired(const sp<const DisplayDevice>& hw) {
2083c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden    ALOGD("Screen acquired, type=%d flinger=%p", hw->getDisplayType(), this);
2084c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden    if (hw->isScreenAcquired()) {
2085c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        // this is expected, e.g. when power manager wakes up during boot
2086c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        ALOGD(" screen was previously acquired");
2087c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        return;
2088c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden    }
2089c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden
20904297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->acquireScreen();
2091c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden    int32_t type = hw->getDisplayType();
2092c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden    if (type < DisplayDevice::NUM_DISPLAY_TYPES) {
2093c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        // built-in display, tell the HWC
2094c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        getHwComposer().acquire(type);
2095c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden
2096c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        if (type == DisplayDevice::DISPLAY_PRIMARY) {
2097c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden            // FIXME: eventthread only knows about the main display right now
2098c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden            mEventThread->onScreenAcquired();
2099c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        }
2100cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian    }
210120128300e0cb7f459a60cfbcddb48190ce6545edMathias Agopian    mVisibleRegionsDirty = true;
210220128300e0cb7f459a60cfbcddb48190ce6545edMathias Agopian    repaintEverything();
2103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2105cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopianvoid SurfaceFlinger::onScreenReleased(const sp<const DisplayDevice>& hw) {
2106c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden    ALOGD("Screen released, type=%d flinger=%p", hw->getDisplayType(), this);
2107c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden    if (!hw->isScreenAcquired()) {
2108c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        ALOGD(" screen was previously released");
2109c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        return;
2110c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden    }
2111c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden
2112c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden    hw->releaseScreen();
2113c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden    int32_t type = hw->getDisplayType();
2114c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden    if (type < DisplayDevice::NUM_DISPLAY_TYPES) {
2115c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        if (type == DisplayDevice::DISPLAY_PRIMARY) {
2116cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian            // FIXME: eventthread only knows about the main display right now
2117cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian            mEventThread->onScreenReleased();
2118cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian        }
2119c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden
2120c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        // built-in display, tell the HWC
2121c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        getHwComposer().release(type);
2122b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    }
2123c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden    mVisibleRegionsDirty = true;
2124c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden    // from this point on, SF will stop drawing on this display
2125b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian}
2126b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
2127c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFaddenvoid SurfaceFlinger::unblank(const sp<IBinder>& display) {
2128b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    class MessageScreenAcquired : public MessageBase {
2129db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian        SurfaceFlinger& mFlinger;
2130db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian        sp<IBinder> mDisplay;
2131b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    public:
2132db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian        MessageScreenAcquired(SurfaceFlinger& flinger,
2133db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian                const sp<IBinder>& disp) : mFlinger(flinger), mDisplay(disp) { }
2134b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        virtual bool handler() {
2135db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian            const sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay));
2136db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian            if (hw == NULL) {
2137db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian                ALOGE("Attempt to unblank null display %p", mDisplay.get());
2138db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian            } else if (hw->getDisplayType() >= DisplayDevice::NUM_DISPLAY_TYPES) {
2139db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian                ALOGW("Attempt to unblank virtual display");
2140db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian            } else {
2141db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian                mFlinger.onScreenAcquired(hw);
2142db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian            }
2143b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            return true;
2144b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        }
2145b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    };
2146db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian    sp<MessageBase> msg = new MessageScreenAcquired(*this, display);
2147db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian    postMessageSync(msg);
2148edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2149edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2150c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFaddenvoid SurfaceFlinger::blank(const sp<IBinder>& display) {
2151b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    class MessageScreenReleased : public MessageBase {
2152db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian        SurfaceFlinger& mFlinger;
2153db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian        sp<IBinder> mDisplay;
2154b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    public:
2155db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian        MessageScreenReleased(SurfaceFlinger& flinger,
2156db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian                const sp<IBinder>& disp) : mFlinger(flinger), mDisplay(disp) { }
2157b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        virtual bool handler() {
2158db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian            const sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay));
2159db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian            if (hw == NULL) {
2160db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian                ALOGE("Attempt to blank null display %p", mDisplay.get());
2161db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian            } else if (hw->getDisplayType() >= DisplayDevice::NUM_DISPLAY_TYPES) {
2162db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian                ALOGW("Attempt to blank virtual display");
2163db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian            } else {
2164db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian                mFlinger.onScreenReleased(hw);
2165db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian            }
2166b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            return true;
2167b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        }
2168b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    };
2169db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian    sp<MessageBase> msg = new MessageScreenReleased(*this, display);
2170db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian    postMessageSync(msg);
2171b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian}
2172b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
2173b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// ---------------------------------------------------------------------------
2174b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
2175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
2176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
21771d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling    const size_t SIZE = 4096;
2178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char buffer[SIZE];
2179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    String8 result;
218099b49840d309727678b77403d6cc9f920111623fMathias Agopian
218199b49840d309727678b77403d6cc9f920111623fMathias Agopian    if (!PermissionCache::checkCallingPermission(sDump)) {
2182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        snprintf(buffer, SIZE, "Permission Denial: "
2183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                "can't dump SurfaceFlinger from pid=%d, uid=%d\n",
2184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                IPCThreadState::self()->getCallingPid(),
2185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                IPCThreadState::self()->getCallingUid());
2186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        result.append(buffer);
2187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
21889795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // Try to get the main lock, but don't insist if we can't
21899795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // (this would indicate SF is stuck, but we want to be able to
21909795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // print something in dumpsys).
21919795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        int retry = 3;
21929795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        while (mStateLock.tryLock()<0 && --retry>=0) {
21939795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            usleep(1000000);
21949795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
21959795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const bool locked(retry >= 0);
21969795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (!locked) {
21978b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber            snprintf(buffer, SIZE,
21989795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "SurfaceFlinger appears to be unresponsive, "
21999795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "dumping anyways (no locks held)\n");
22009795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            result.append(buffer);
22019795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
22029795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
220382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        bool dumpAll = true;
220482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        size_t index = 0;
220525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        size_t numArgs = args.size();
220625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        if (numArgs) {
220725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
220825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--list"))) {
220925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                index++;
221025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                listLayersLocked(args, index, result, buffer, SIZE);
221135aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
221225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            }
221325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
221425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
221525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--latency"))) {
221682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                index++;
221782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                dumpStatsLocked(args, index, result, buffer, SIZE);
221835aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
221982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            }
222025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
222125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
222225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--latency-clear"))) {
222325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                index++;
222425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                clearStatsLocked(args, index, result, buffer, SIZE);
222535aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
222625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            }
2227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
22281b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
222982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (dumpAll) {
223082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            dumpAllLocked(result, buffer, SIZE);
223182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
223248b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
223382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (locked) {
223482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mStateLock.unlock();
223548b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        }
223682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
223782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    write(fd, result.string(), result.size());
223882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    return NO_ERROR;
223982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
224048b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
224125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::listLayersLocked(const Vector<String16>& args, size_t& index,
224225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        String8& result, char* buffer, size_t SIZE) const
224325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
224425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
224525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const size_t count = currentLayers.size();
224625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
224725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
224825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        snprintf(buffer, SIZE, "%s\n", layer->getName().string());
224925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        result.append(buffer);
225025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
225125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
225225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
225382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index,
225482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        String8& result, char* buffer, size_t SIZE) const
225582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
225682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    String8 name;
225782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    if (index < args.size()) {
225882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        name = String8(args[index]);
225982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        index++;
226082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
226148b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
226282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
226382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const size_t count = currentLayers.size();
226482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    for (size_t i=0 ; i<count ; i++) {
226582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
226682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (name.isEmpty()) {
226782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            snprintf(buffer, SIZE, "%s\n", layer->getName().string());
226882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            result.append(buffer);
226982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
227082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (name.isEmpty() || (name == layer->getName())) {
227182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            layer->dumpStats(result, buffer, SIZE);
227282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
227382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
227482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
2275ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian
227625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& index,
227725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        String8& result, char* buffer, size_t SIZE) const
227825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
227925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    String8 name;
228025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    if (index < args.size()) {
228125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        name = String8(args[index]);
228225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        index++;
228325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
228425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
228525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
228625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const size_t count = currentLayers.size();
228725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
228825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
228925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        if (name.isEmpty() || (name == layer->getName())) {
229025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            layer->clearStats();
229125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        }
229225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
229325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
229425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
22954803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden/*static*/ void SurfaceFlinger::appendSfConfigString(String8& result)
22964803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden{
22974803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    static const char* config =
22984803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden            " [sf"
22994803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#ifdef NO_RGBX_8888
23004803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden            " NO_RGBX_8888"
23014803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#endif
23024803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#ifdef HAS_CONTEXT_PRIORITY
23034803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden            " HAS_CONTEXT_PRIORITY"
23044803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#endif
23054803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#ifdef NEVER_DEFAULT_TO_ASYNC_MODE
23064803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden            " NEVER_DEFAULT_TO_ASYNC_MODE"
23074803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#endif
23084803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
23094803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden            " TARGET_DISABLE_TRIPLE_BUFFERING"
23104803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#endif
23114803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden            "]";
23124803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    result.append(config);
23134803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden}
23144803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden
231582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpAllLocked(
231682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        String8& result, char* buffer, size_t SIZE) const
231782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
231882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    // figure out if we're stuck somewhere
231982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t now = systemTime();
232082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t inSwapBuffers(mDebugInSwapBuffers);
232182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t inTransaction(mDebugInTransaction);
232282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0;
232382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0;
2324bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
232582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
23264803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden     * Dump library configuration.
23274803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden     */
23284803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    result.append("Build configuration:");
23294803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    appendSfConfigString(result);
23304803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    appendUiConfigString(result);
23314803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    appendGuiConfigString(result);
23324803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    result.append("\n");
23334803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden
23344803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    /*
233582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump the visible layer list
233682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
233782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
233882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const size_t count = currentLayers.size();
233982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "Visible layers (count = %d)\n", count);
234082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
234182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    for (size_t i=0 ; i<count ; i++) {
234282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
234382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        layer->dump(result, buffer, SIZE);
234482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
2345bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
234682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
234782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump the layers in the purgatory
234882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
2349ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian
235082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const size_t purgatorySize = mLayerPurgatory.size();
235182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "Purgatory state (%d entries)\n", purgatorySize);
235282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
235382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    for (size_t i=0 ; i<purgatorySize ; i++) {
235482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
235582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        layer->shortDump(result, buffer, SIZE);
235682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
23571b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
235882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
23595f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian     * Dump Display state
23605f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian     */
23615f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian
23628dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden    snprintf(buffer, SIZE, "Displays (%d entries)\n", mDisplays.size());
23638dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden    result.append(buffer);
23645f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
23655f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        const sp<const DisplayDevice>& hw(mDisplays[dpy]);
23661d12d8a8e61163b35cf42c51c558a67138014e82Mathias Agopian        hw->dump(result, buffer, SIZE);
23675f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    }
23685f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian
23695f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    /*
237082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump SurfaceFlinger global state
237182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
23721b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
237382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "SurfaceFlinger global state:\n");
237482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
23751b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
2376888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian    HWComposer& hwc(getHwComposer());
23774297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    sp<const DisplayDevice> hw(getDefaultDisplayDevice());
237882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const GLExtensions& extensions(GLExtensions::getInstance());
237982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "GLES: %s, %s, %s\n",
238082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            extensions.getVendor(),
238182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            extensions.getRenderer(),
238282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            extensions.getVersion());
238382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
2384d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
238582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "EGL : %s\n",
2386d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian            eglQueryString(mEGLDisplay, EGL_VERSION_HW_ANDROID));
238782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
238873d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian
238982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "EXTS: %s\n", extensions.getExtension());
239082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
23919795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
23924297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->undefinedRegion.dump(result, "undefinedRegion");
239382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE,
239482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  orientation=%d, canDraw=%d\n",
23954297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->getOrientation(), hw->canDraw());
239682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
239782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE,
239882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  last eglSwapBuffers() time: %f us\n"
239982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  last transaction time     : %f us\n"
2400c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian            "  transaction-flags         : %08x\n"
240182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  refresh-rate              : %f fps\n"
240282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  x-dpi                     : %f\n"
24038b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            "  y-dpi                     : %f\n",
240482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mLastSwapBufferTime/1000.0,
240582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mLastTransactionTime/1000.0,
2406c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian            mTransactionFlags,
2407b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden            1e9 / hwc.getRefreshPeriod(HWC_DISPLAY_PRIMARY),
2408b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden            hwc.getDpiX(HWC_DISPLAY_PRIMARY),
2409b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden            hwc.getDpiY(HWC_DISPLAY_PRIMARY));
241082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
241182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
241282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "  eglSwapBuffers time: %f us\n",
241382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            inSwapBuffersDuration/1000.0);
241482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
241582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
241682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "  transaction time: %f us\n",
241782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            inTransactionDuration/1000.0);
241882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
241982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
242082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
242182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * VSYNC state
242282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
242382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    mEventThread->dump(result, buffer, SIZE);
242482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
242582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
242682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump HWComposer state
242782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
242882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "h/w composer state:\n");
242982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
243082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "  h/w composer %s and %s\n",
243182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            hwc.initCheck()==NO_ERROR ? "present" : "not present",
243282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                    (mDebugDisableHWC || mDebugRegion) ? "disabled" : "enabled");
243382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
2434cb55857bbde34a06c19dde3db5064d1717a0173eMathias Agopian    hwc.dump(result, buffer, SIZE);
243582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
243682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
243782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump gralloc state
243882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
243982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
244082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    alloc.dump(result);
2441edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2442edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2443cb55857bbde34a06c19dde3db5064d1717a0173eMathias Agopianconst Vector< sp<LayerBase> >&
2444cb55857bbde34a06c19dde3db5064d1717a0173eMathias AgopianSurfaceFlinger::getLayerSortedByZForHwcDisplay(int disp) {
2445db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian    // Note: mStateLock is held here
2446cb55857bbde34a06c19dde3db5064d1717a0173eMathias Agopian    return getDisplayDevice( getBuiltInDisplay(disp) )->getVisibleLayersSortedByZ();
2447cb55857bbde34a06c19dde3db5064d1717a0173eMathias Agopian}
2448cb55857bbde34a06c19dde3db5064d1717a0173eMathias Agopian
244963f165fd6b86d04be94d4023e845e98560504a96Keun young Parkbool SurfaceFlinger::startDdmConnection()
245063f165fd6b86d04be94d4023e845e98560504a96Keun young Park{
245163f165fd6b86d04be94d4023e845e98560504a96Keun young Park    void* libddmconnection_dso =
245263f165fd6b86d04be94d4023e845e98560504a96Keun young Park            dlopen("libsurfaceflinger_ddmconnection.so", RTLD_NOW);
245363f165fd6b86d04be94d4023e845e98560504a96Keun young Park    if (!libddmconnection_dso) {
245463f165fd6b86d04be94d4023e845e98560504a96Keun young Park        return false;
245563f165fd6b86d04be94d4023e845e98560504a96Keun young Park    }
245663f165fd6b86d04be94d4023e845e98560504a96Keun young Park    void (*DdmConnection_start)(const char* name);
245763f165fd6b86d04be94d4023e845e98560504a96Keun young Park    DdmConnection_start =
245863f165fd6b86d04be94d4023e845e98560504a96Keun young Park            (typeof DdmConnection_start)dlsym(libddmconnection_dso, "DdmConnection_start");
245963f165fd6b86d04be94d4023e845e98560504a96Keun young Park    if (!DdmConnection_start) {
246063f165fd6b86d04be94d4023e845e98560504a96Keun young Park        dlclose(libddmconnection_dso);
246163f165fd6b86d04be94d4023e845e98560504a96Keun young Park        return false;
246263f165fd6b86d04be94d4023e845e98560504a96Keun young Park    }
246363f165fd6b86d04be94d4023e845e98560504a96Keun young Park    (*DdmConnection_start)(getServiceName());
246463f165fd6b86d04be94d4023e845e98560504a96Keun young Park    return true;
246563f165fd6b86d04be94d4023e845e98560504a96Keun young Park}
246663f165fd6b86d04be94d4023e845e98560504a96Keun young Park
2467edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::onTransact(
2468edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
2469edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2470edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (code) {
2471edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case CREATE_CONNECTION:
2472698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        case SET_TRANSACTION_STATE:
2473edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case BOOT_FINISHED:
24748e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross        case BLANK:
24758e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross        case UNBLANK:
2476edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        {
2477edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // codes that require permission check
2478edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            IPCThreadState* ipc = IPCThreadState::self();
2479edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int pid = ipc->getCallingPid();
2480a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian            const int uid = ipc->getCallingUid();
248199b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
248299b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) {
2483e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block                ALOGE("Permission Denial: "
2484375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                        "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
2485375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                return PERMISSION_DENIED;
2486edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
24871b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
24881b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
24891b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        case CAPTURE_SCREEN:
24901b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
24911b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            // codes that require permission check
24921b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
24931b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int pid = ipc->getCallingPid();
24941b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int uid = ipc->getCallingUid();
249599b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
249699b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) {
2497e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block                ALOGE("Permission Denial: "
24981b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                        "can't read framebuffer pid=%d, uid=%d", pid, uid);
24991b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                return PERMISSION_DENIED;
25001b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            }
25011b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
2502edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
2503edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
25041b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
2505edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
2506edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
2507b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        CHECK_INTERFACE(ISurfaceComposer, data, reply);
250899ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten        if (CC_UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) {
2509375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
2510375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int pid = ipc->getCallingPid();
2511375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int uid = ipc->getCallingUid();
2512e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block            ALOGE("Permission Denial: "
2513375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                    "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
2514edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return PERMISSION_DENIED;
2515edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
2516edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int n;
2517edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        switch (code) {
251801b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian            case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE
251935b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian            case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE
2520edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
2521edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1002:  // SHOW_UPDATES
2522edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                n = data.readInt32();
2523edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDebugRegion = n ? n : (mDebugRegion ? 0 : 1);
252453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
252553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
2526edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
2527edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1004:{ // repaint everything
252853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
2529cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
2530cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            }
2531cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            case 1005:{ // force transaction
2532e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                setTransactionFlags(
2533e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        eTransactionNeeded|
2534e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        eDisplayTransactionNeeded|
2535e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        eTraversalNeeded);
2536cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
2537edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
25384d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            case 1006:{ // send empty update
25394d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian                signalRefresh();
25404d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian                return NO_ERROR;
25414d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            }
254253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian            case 1008:  // toggle use of hw composer
254353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                n = data.readInt32();
254453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                mDebugDisableHWC = n ? 1 : 0;
254553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
254653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
254753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                return NO_ERROR;
2548a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian            case 1009:  // toggle use of transform hint
2549a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                n = data.readInt32();
2550a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                mDebugDisableTransformHint = n ? 1 : 0;
2551a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                invalidateHwcGeometry();
2552a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                repaintEverything();
2553a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                return NO_ERROR;
2554edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1010:  // interrogate.
255501b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian                reply->writeInt32(0);
2556edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(0);
2557edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(mDebugRegion);
2558b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                reply->writeInt32(0);
255912839bee29bdcc65731b4d42029cc59e2320c5c4Dianne Hackborn                reply->writeInt32(mDebugDisableHWC);
2560edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
2561edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1013: {
2562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                Mutex::Autolock _l(mStateLock);
25634297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                sp<const DisplayDevice> hw(getDefaultDisplayDevice());
25644297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                reply->writeInt32(hw->getPageFlipCount());
2565edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
2566edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return NO_ERROR;
2567edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
2568edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2569edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return err;
2570edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2571edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
257253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopianvoid SurfaceFlinger::repaintEverything() {
257387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    android_atomic_or(1, &mRepaintEverything);
257499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    signalTransaction();
257553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian}
257653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian
257759119e658a12279e8fff508f8773843de2d90917Mathias Agopian// ---------------------------------------------------------------------------
257859119e658a12279e8fff508f8773843de2d90917Mathias Agopian
25793ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopianstatus_t SurfaceFlinger::renderScreenToTexture(uint32_t layerStack,
2580118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        GLuint* textureName, GLfloat* uOut, GLfloat* vOut)
2581118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{
2582118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    Mutex::Autolock _l(mStateLock);
25833ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    return renderScreenToTextureLocked(layerStack, textureName, uOut, vOut);
2584118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
2585118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
25863ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopianstatus_t SurfaceFlinger::renderScreenToTextureLocked(uint32_t layerStack,
25879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        GLuint* textureName, GLfloat* uOut, GLfloat* vOut)
258859119e658a12279e8fff508f8773843de2d90917Mathias Agopian{
258922ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian    ATRACE_CALL();
259022ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian
259159119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
259259119e658a12279e8fff508f8773843de2d90917Mathias Agopian        return INVALID_OPERATION;
259359119e658a12279e8fff508f8773843de2d90917Mathias Agopian
259459119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // get screen geometry
25953ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    // FIXME: figure out what it means to have a screenshot texture w/ multi-display
25963ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    sp<const DisplayDevice> hw(getDefaultDisplayDevice());
25974297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const uint32_t hw_w = hw->getWidth();
25984297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const uint32_t hw_h = hw->getHeight();
259959119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLfloat u = 1;
260059119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLfloat v = 1;
260159119e658a12279e8fff508f8773843de2d90917Mathias Agopian
260259119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // make sure to clear all GL error flags
260359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    while ( glGetError() != GL_NO_ERROR ) ;
260459119e658a12279e8fff508f8773843de2d90917Mathias Agopian
260559119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // create a FBO
260659119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLuint name, tname;
260759119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glGenTextures(1, &tname);
260859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
2609a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2610a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
26119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
26129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            hw_w, hw_h, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
261359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (glGetError() != GL_NO_ERROR) {
2614015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian        while ( glGetError() != GL_NO_ERROR ) ;
261559119e658a12279e8fff508f8773843de2d90917Mathias Agopian        GLint tw = (2 << (31 - clz(hw_w)));
261659119e658a12279e8fff508f8773843de2d90917Mathias Agopian        GLint th = (2 << (31 - clz(hw_h)));
26179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
26189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian                tw, th, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
261959119e658a12279e8fff508f8773843de2d90917Mathias Agopian        u = GLfloat(hw_w) / tw;
262059119e658a12279e8fff508f8773843de2d90917Mathias Agopian        v = GLfloat(hw_h) / th;
262159119e658a12279e8fff508f8773843de2d90917Mathias Agopian    }
262259119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glGenFramebuffersOES(1, &name);
262359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
26249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES,
26259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0);
262659119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2627bae92d0d605e99a14731add4f11b72413b2835e5Mathias Agopian    DisplayDevice::setViewportAndProjection(hw);
2628bae92d0d605e99a14731add4f11b72413b2835e5Mathias Agopian
26299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // redraw the screen entirely...
2630c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_EXTERNAL_OES);
2631c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_2D);
26329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glClearColor(0,0,0,1);
26339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glClear(GL_COLOR_BUFFER_BIT);
2634a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glMatrixMode(GL_MODELVIEW);
2635a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glLoadIdentity();
26364297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const Vector< sp<LayerBase> >& layers(hw->getVisibleLayersSortedByZ());
26379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const size_t count = layers.size();
26389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (size_t i=0 ; i<count ; ++i) {
26399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
2640fcb239d3dac8bc80f28177f1951611c1d43286ffMathias Agopian        layer->draw(hw);
26419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
264259119e658a12279e8fff508f8773843de2d90917Mathias Agopian
26434297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->compositionComplete();
2644118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
26459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // back to main framebuffer
26469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
26479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDeleteFramebuffersOES(1, &name);
264859119e658a12279e8fff508f8773843de2d90917Mathias Agopian
26499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *textureName = tname;
26509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *uOut = u;
26519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *vOut = v;
26529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
26539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
265459119e658a12279e8fff508f8773843de2d90917Mathias Agopian
26559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// ---------------------------------------------------------------------------
26569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
26579d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brownstatus_t SurfaceFlinger::captureScreenImplLocked(const sp<IBinder>& display,
265874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        sp<IMemoryHeap>* heap,
265974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t* w, uint32_t* h, PixelFormat* f,
2660bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t sw, uint32_t sh,
2661bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ, uint32_t maxLayerZ)
266274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{
2663fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian    ATRACE_CALL();
2664fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian
266574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    status_t result = PERMISSION_DENIED;
266674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
26673b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject()) {
266874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return INVALID_OPERATION;
26693b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
267074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
267174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // get screen geometry
26723ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    sp<const DisplayDevice> hw(getDisplayDevice(display));
26734297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const uint32_t hw_w = hw->getWidth();
26744297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const uint32_t hw_h = hw->getHeight();
267574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
26763b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    // if we have secure windows on this display, never allow the screen capture
26774297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    if (hw->getSecureLayerVisible()) {
2678ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian        ALOGW("FB is protected: PERMISSION_DENIED");
26793b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        return PERMISSION_DENIED;
26803b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
26813b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
26823b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    if ((sw > hw_w) || (sh > hw_h)) {
2683ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian        ALOGE("size mismatch (%d, %d) > (%d, %d)", sw, sh, hw_w, hw_h);
268474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return BAD_VALUE;
26853b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
268674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
268774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    sw = (!sw) ? hw_w : sw;
268874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    sh = (!sh) ? hw_h : sh;
268974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const size_t size = sw * sh * 4;
2690fcb239d3dac8bc80f28177f1951611c1d43286ffMathias Agopian    const bool filtering = sw != hw_w || sh != hw_h;
269174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
2692ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian//    ALOGD("screenshot: sw=%d, sh=%d, minZ=%d, maxZ=%d",
2693ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian//            sw, sh, minLayerZ, maxLayerZ);
2694c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
269574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // make sure to clear all GL error flags
269674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    while ( glGetError() != GL_NO_ERROR ) ;
269774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
269874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // create a FBO
269974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    GLuint name, tname;
270074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glGenRenderbuffersOES(1, &tname);
270174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindRenderbufferOES(GL_RENDERBUFFER_OES, tname);
270274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA8_OES, sw, sh);
2703fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian
270474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glGenFramebuffersOES(1, &name);
270574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
270674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES,
270774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, tname);
270874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
270974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
2710c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
271174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    if (status == GL_FRAMEBUFFER_COMPLETE_OES) {
271274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
271374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // invert everything, b/c glReadPixel() below will invert the FB
2714135e5899f70a67e62baaf6dbec7ba2ce611ca16aMathias Agopian        GLint  viewport[4];
2715135e5899f70a67e62baaf6dbec7ba2ce611ca16aMathias Agopian        glGetIntegerv(GL_VIEWPORT, viewport);
271674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glViewport(0, 0, sw, sh);
271774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_PROJECTION);
271874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glPushMatrix();
271974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glLoadIdentity();
2720ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian        glOrthof(0, hw_w, hw_h, 0, 0, 1);
272174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_MODELVIEW);
272274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
272374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // redraw the screen entirely...
272474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glClearColor(0,0,0,1);
272574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
2726f653b897a449e10d6cbfb6e0812f7b0bb02d6482Mathias Agopian
27273ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian        const Vector< sp<LayerBase> >& layers(hw->getVisibleLayersSortedByZ());
27289575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        const size_t count = layers.size();
272974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        for (size_t i=0 ; i<count ; ++i) {
273074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            const sp<LayerBase>& layer(layers[i]);
27313ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian            const uint32_t z = layer->drawingState().z;
27323ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian            if (z >= minLayerZ && z <= maxLayerZ) {
27333ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian                if (filtering) layer->setFiltering(true);
27343ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian                layer->draw(hw);
27353ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian                if (filtering) layer->setFiltering(false);
2736bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian            }
273774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        }
273874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
273974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // check for errors and return screen capture
274074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        if (glGetError() != GL_NO_ERROR) {
274174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // error while rendering
274274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            result = INVALID_OPERATION;
274374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        } else {
274474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // allocate shared memory large enough to hold the
274574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // screen capture
274674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            sp<MemoryHeapBase> base(
274774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    new MemoryHeapBase(size, 0, "screen-capture") );
274874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            void* const ptr = base->getBase();
27497b1905113712281c777b230648d3fbb69ae4f42cMathias Agopian            if (ptr != MAP_FAILED) {
275074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                // capture the screen with glReadPixels()
2751fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian                ScopedTrace _t(ATRACE_TAG, "glReadPixels");
275274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                glReadPixels(0, 0, sw, sh, GL_RGBA, GL_UNSIGNED_BYTE, ptr);
275374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                if (glGetError() == GL_NO_ERROR) {
275474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *heap = base;
275574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *w = sw;
275674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *h = sh;
275774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *f = PIXEL_FORMAT_RGBA_8888;
275874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    result = NO_ERROR;
275974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                }
276074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            } else {
276174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                result = NO_MEMORY;
276274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            }
276374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        }
2764135e5899f70a67e62baaf6dbec7ba2ce611ca16aMathias Agopian        glViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
276574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_PROJECTION);
276674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glPopMatrix();
276774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_MODELVIEW);
276874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    } else {
276974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        result = BAD_VALUE;
277074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    }
277174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
277274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // release FBO resources
277374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
277474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glDeleteRenderbuffersOES(1, &tname);
277574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glDeleteFramebuffersOES(1, &name);
2776e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian
27774297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->compositionComplete();
2778e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian
2779ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian//    ALOGD("screenshot: result = %s", result<0 ? strerror(result) : "OK");
2780c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
278174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    return result;
278274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian}
278374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
278474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
27859d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brownstatus_t SurfaceFlinger::captureScreen(const sp<IBinder>& display,
27861b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        sp<IMemoryHeap>* heap,
278774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t* width, uint32_t* height, PixelFormat* format,
2788bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t sw, uint32_t sh,
2789bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ, uint32_t maxLayerZ)
27901b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian{
27919d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown    if (CC_UNLIKELY(display == 0))
27921b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        return BAD_VALUE;
27931b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
27941b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
27951b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        return INVALID_OPERATION;
27961b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
27971b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    class MessageCaptureScreen : public MessageBase {
27981b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        SurfaceFlinger* flinger;
27999d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown        sp<IBinder> display;
28001b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        sp<IMemoryHeap>* heap;
28011b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        uint32_t* w;
28021b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        uint32_t* h;
28031b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        PixelFormat* f;
280474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t sw;
280574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t sh;
2806bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ;
2807bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t maxLayerZ;
28081b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        status_t result;
28091b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    public:
28109d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown        MessageCaptureScreen(SurfaceFlinger* flinger, const sp<IBinder>& display,
281174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                sp<IMemoryHeap>* heap, uint32_t* w, uint32_t* h, PixelFormat* f,
2812bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                uint32_t sw, uint32_t sh,
2813bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                uint32_t minLayerZ, uint32_t maxLayerZ)
28149d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown            : flinger(flinger), display(display),
2815bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              heap(heap), w(w), h(h), f(f), sw(sw), sh(sh),
2816bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              minLayerZ(minLayerZ), maxLayerZ(maxLayerZ),
2817bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              result(PERMISSION_DENIED)
28181b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
28191b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
28201b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        status_t getResult() const {
28211b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            return result;
28221b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
28231b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        virtual bool handler() {
28241b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
28259d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown            result = flinger->captureScreenImplLocked(display,
2826bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                    heap, w, h, f, sw, sh, minLayerZ, maxLayerZ);
28271b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            return true;
28281b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
28291b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    };
28301b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
28311b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    sp<MessageBase> msg = new MessageCaptureScreen(this,
28329d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown            display, heap, width, height, format, sw, sh, minLayerZ, maxLayerZ);
28331b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    status_t res = postMessageSync(msg);
28341b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    if (res == NO_ERROR) {
28351b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        res = static_cast<MessageCaptureScreen*>( msg.get() )->getResult();
28361b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    }
28371b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    return res;
28381b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian}
28391b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
28401b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// ---------------------------------------------------------------------------
28411b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
2842921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::LayerVector::LayerVector() {
2843921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
2844921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
2845921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::LayerVector::LayerVector(const LayerVector& rhs)
2846921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    : SortedVector<sp<LayerBase> >(rhs) {
2847921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
2848921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
2849921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianint SurfaceFlinger::LayerVector::do_compare(const void* lhs,
2850921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    const void* rhs) const
2851edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2852be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    // sort layers per layer-stack, then by z-order and finally by sequence
2853921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    const sp<LayerBase>& l(*reinterpret_cast<const sp<LayerBase>*>(lhs));
2854921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    const sp<LayerBase>& r(*reinterpret_cast<const sp<LayerBase>*>(rhs));
2855be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian
2856be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    uint32_t ls = l->currentState().layerStack;
2857be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    uint32_t rs = r->currentState().layerStack;
2858be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    if (ls != rs)
2859be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian        return ls - rs;
2860be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian
2861921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    uint32_t lz = l->currentState().z;
2862921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    uint32_t rz = r->currentState().z;
2863be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    if (lz != rz)
2864be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian        return lz - rz;
2865be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian
2866be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    return l->sequence - r->sequence;
2867921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
2868921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
2869921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian// ---------------------------------------------------------------------------
2870921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
28713ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias AgopianSurfaceFlinger::DisplayDeviceState::DisplayDeviceState()
28723ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    : type(DisplayDevice::DISPLAY_ID_INVALID) {
2873e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
2874e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
28753ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias AgopianSurfaceFlinger::DisplayDeviceState::DisplayDeviceState(DisplayDevice::DisplayType type)
28763ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    : type(type), layerStack(0), orientation(0) {
2877da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian    viewport.makeInvalid();
2878da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian    frame.makeInvalid();
2879b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
28807303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
2881b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// ---------------------------------------------------------------------------
288296f0819f81293076e652792794a961543e6750d7Mathias Agopian
2883edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
2884