SurfaceFlinger.cpp revision 3559b07a885bcdff51a6dffb8e3a5ac5adf3a220
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>
23921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
24921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <EGL/egl.h>
25921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <GLES/gl.h>
26edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
27edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/log.h>
28edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/properties.h>
29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
30c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IPCThreadState.h>
31c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IServiceManager.h>
327303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian#include <binder/MemoryHeapBase.h>
3399b49840d309727678b77403d6cc9f920111623fMathias Agopian#include <binder/PermissionCache.h>
347303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
35c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian#include <ui/DisplayInfo.h>
36c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian
37921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <gui/BitTube.h>
381a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <gui/BufferQueue.h>
391a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <gui/IDisplayEventConnection.h>
40921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <gui/SurfaceTextureClient.h>
41921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
42921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <ui/GraphicBufferAllocator.h>
43921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <ui/PixelFormat.h>
44d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String8.h>
46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String16.h>
47edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/StopWatch.h>
481c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#include <utils/Trace.h>
49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
50921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <private/android_filesystem_config.h>
51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h"
5390ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include "DdmConnection.h"
540f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian#include "DisplayDevice.h"
55db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian#include "Client.h"
56d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian#include "EventThread.h"
571f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian#include "GLExtensions.h"
58edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h"
59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerDim.h"
60118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian#include "LayerScreenshot.h"
61edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h"
62edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
63a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#include "DisplayHardware/FramebufferSurface.h"
64a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian#include "DisplayHardware/HWComposer.h"
65edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
66a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
67bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian#define EGL_VERSION_HW_ANDROID  0x3143
68bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DISPLAY_COUNT       1
70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
73edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
7499b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sHardwareTest("android.permission.HARDWARE_TEST");
7599b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER");
7699b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER");
7799b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sDump("android.permission.DUMP");
7899b49840d309727678b77403d6cc9f920111623fMathias Agopian
7999b49840d309727678b77403d6cc9f920111623fMathias Agopian// ---------------------------------------------------------------------------
8099b49840d309727678b77403d6cc9f920111623fMathias Agopian
81edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::SurfaceFlinger()
82edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    :   BnSurfaceComposer(), Thread(false),
83edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mTransactionFlags(0),
8428378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        mTransationPending(false),
85076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved(false),
8652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        mRepaintEverything(0),
87edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mBootTime(systemTime()),
88edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mVisibleRegionsDirty(false),
89a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        mHwWorkListDirty(false),
90edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDebugRegion(0),
918afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian        mDebugDDMS(0),
9273d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian        mDebugDisableHWC(0),
93a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian        mDebugDisableTransformHint(0),
949795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInSwapBuffers(0),
959795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastSwapBufferTime(0),
969795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInTransaction(0),
979795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastTransactionTime(0),
983330b203039dea366d4981db1408a460134b2d2cMathias Agopian        mBootFinished(false),
993094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        mExternalDisplaySurface(EGL_NO_SURFACE)
100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
101a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI("SurfaceFlinger is starting");
102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // debugging stuff...
104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char value[PROPERTY_VALUE_MAX];
1058afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    property_get("debug.sf.showupdates", value, "0");
107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDebugRegion = atoi(value);
1088afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
1098afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    property_get("debug.sf.ddms", value, "0");
1108afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    mDebugDDMS = atoi(value);
1118afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    if (mDebugDDMS) {
1128afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian        DdmConnection::start(getServiceName());
1138afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    }
1148afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
115c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    ALOGI_IF(mDebugRegion, "showupdates enabled");
116c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    ALOGI_IF(mDebugDDMS, "DDMS debugging enabled");
117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
11999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::onFirstRef()
12099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
12199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.init(this);
12299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
12399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY);
12499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
12599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // Wait for the main thread to be done with its initialization
12699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mReadyToRunBarrier.wait();
12799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
12899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
12999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::~SurfaceFlinger()
131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
132a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
133a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
134a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglTerminate(display);
135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
13799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::binderDied(const wp<IBinder>& who)
13899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
13999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // the window manager died on us. prepare its eulogy.
14099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
14199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // reset screen orientation
14299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    Vector<ComposerState> state;
1438b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian    Vector<DisplayState> displays;
1448b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian    DisplayState d;
145ea599dfff03b45903dae3288274c31cb24fd483fJesse Hall    d.what = DisplayState::eTransformChanged;
146ea599dfff03b45903dae3288274c31cb24fd483fJesse Hall    d.token = mDefaultDisplays[DisplayDevice::DISPLAY_ID_MAIN];
1473165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian    d.orientation = DisplayState::eOrientationDefault;
1488b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian    displays.add(d);
1498b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian    setTransactionState(state, displays, 0);
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
166e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopiansp<IBinder> SurfaceFlinger::createDisplay()
167e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{
168e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    class DisplayToken : public BBinder {
169e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        sp<SurfaceFlinger> flinger;
170e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        virtual ~DisplayToken() {
171e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             // no more references, this display must be terminated
172e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             Mutex::Autolock _l(flinger->mStateLock);
173e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             flinger->mCurrentState.displays.removeItem(this);
174e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             flinger->setTransactionFlags(eDisplayTransactionNeeded);
175e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian         }
176e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian     public:
177e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        DisplayToken(const sp<SurfaceFlinger>& flinger)
178e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            : flinger(flinger) {
179e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
180e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    };
181e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
182e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    sp<BBinder> token = new DisplayToken(this);
183e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
184e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    Mutex::Autolock _l(mStateLock);
185e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    DisplayDeviceState info(intptr_t(token.get())); // FIXME: we shouldn't use the address for the id
186e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    mCurrentState.displays.add(token, info);
187e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
188e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return token;
189e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
190e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
191e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopiansp<IBinder> SurfaceFlinger::getBuiltInDisplay(int32_t id) {
192e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    if (uint32_t(id) >= DisplayDevice::DISPLAY_ID_COUNT) {
193e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        ALOGE("getDefaultDisplay: id=%d is not a valid default display id", id);
194e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        return NULL;
195e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
196e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return mDefaultDisplays[id];
197e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
198e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
1999a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc()
2009a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis{
2019a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc());
2029a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    return gba;
2039a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis}
204b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
205edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::bootFinished()
206edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
207edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t now = systemTime();
208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t duration = now - mBootTime;
209a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
2103330b203039dea366d4981db1408a460134b2d2cMathias Agopian    mBootFinished = true;
2111f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
2121f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // wait patiently for the window manager death
2131f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    const String16 name("window");
2141f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    sp<IBinder> window(defaultServiceManager()->getService(name));
2151f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    if (window != 0) {
216921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        window->linkToDeath(static_cast<IBinder::DeathRecipient*>(this));
2171f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    }
2181f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
2191f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // stop boot animation
220a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // formerly we would just kill the process, but we now ask it to exit so it
221a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // can choose where to stop the animation.
222a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("service.bootanim.exit", "1");
223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
225921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianvoid SurfaceFlinger::deleteTextureAsync(GLuint texture) {
226921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    class MessageDestroyGLTexture : public MessageBase {
227921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        GLuint texture;
228921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    public:
229921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        MessageDestroyGLTexture(GLuint texture)
230921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian            : texture(texture) {
231921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        }
232921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        virtual bool handler() {
233921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian            glDeleteTextures(1, &texture);
234921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian            return true;
235921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        }
236921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    };
237921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    postMessageAsync(new MessageDestroyGLTexture(texture));
238921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
239921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
240a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianstatus_t SurfaceFlinger::selectConfigForPixelFormat(
241a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        EGLDisplay dpy,
242a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        EGLint const* attrs,
243a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        PixelFormat format,
244a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        EGLConfig* outConfig)
245a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian{
246a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLConfig config = NULL;
247a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLint numConfigs = -1, n=0;
248a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglGetConfigs(dpy, NULL, 0, &numConfigs);
249a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLConfig* const configs = new EGLConfig[numConfigs];
250a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglChooseConfig(dpy, attrs, configs, numConfigs, &n);
251a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    for (int i=0 ; i<n ; i++) {
252a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        EGLint nativeVisualId = 0;
253a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        eglGetConfigAttrib(dpy, configs[i], EGL_NATIVE_VISUAL_ID, &nativeVisualId);
254a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        if (nativeVisualId>0 && format == nativeVisualId) {
255a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            *outConfig = configs[i];
256a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            delete [] configs;
257a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            return NO_ERROR;
258a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        }
259a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    }
260a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    delete [] configs;
261a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    return NAME_NOT_FOUND;
262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
264a49126087b4494f4ef50873f3a3f6727265f6621Mathias AgopianEGLConfig SurfaceFlinger::selectEGLConfig(EGLDisplay display, EGLint nativeVisualId) {
265a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // select our EGLConfig. It must support EGL_RECORDABLE_ANDROID if
266a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // it is to be used with WIFI displays
267a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLConfig config;
268a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLint dummy;
269a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    status_t err;
270a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLint attribs[] = {
271a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            EGL_SURFACE_TYPE,           EGL_WINDOW_BIT,
272a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            EGL_RECORDABLE_ANDROID,     EGL_TRUE,
273a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            EGL_NONE
274a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    };
275a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    err = selectConfigForPixelFormat(display, attribs, nativeVisualId, &config);
276a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    if (err) {
277a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        // maybe we failed because of EGL_RECORDABLE_ANDROID
278a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        ALOGW("couldn't find an EGLConfig with EGL_RECORDABLE_ANDROID");
279a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        attribs[2] = EGL_NONE;
280a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        err = selectConfigForPixelFormat(display, attribs, nativeVisualId, &config);
281a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    }
282a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGE_IF(err, "couldn't find an EGLConfig matching the screen format");
283a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    if (eglGetConfigAttrib(display, config, EGL_CONFIG_CAVEAT, &dummy) == EGL_TRUE) {
284a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        ALOGW_IF(dummy == EGL_SLOW_CONFIG, "EGL_SLOW_CONFIG selected!");
285a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    }
286a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    return config;
287a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
288edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
289a49126087b4494f4ef50873f3a3f6727265f6621Mathias AgopianEGLContext SurfaceFlinger::createGLContext(EGLDisplay display, EGLConfig config) {
290a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // Also create our EGLContext
291a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLint contextAttributes[] = {
292a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#ifdef EGL_IMG_context_priority
293a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#ifdef HAS_CONTEXT_PRIORITY
294a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#warning "using EGL_IMG_context_priority"
295a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_HIGH_IMG,
296a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#endif
297a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#endif
298a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            EGL_NONE, EGL_NONE
299a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    };
300a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLContext ctxt = eglCreateContext(display, config, NULL, contextAttributes);
301a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGE_IF(ctxt==EGL_NO_CONTEXT, "EGLContext creation failed");
302a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    return ctxt;
303a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
305a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianvoid SurfaceFlinger::initializeGL(EGLDisplay display, EGLSurface surface) {
306a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLBoolean result = eglMakeCurrent(display, surface, surface, mEGLContext);
307a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    if (!result) {
308a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        ALOGE("Couldn't create a working GLES context. check logs. exiting...");
309a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        exit(0);
310edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
311edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
312a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    GLExtensions& extensions(GLExtensions::getInstance());
313a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    extensions.initWithGLStrings(
314a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            glGetString(GL_VENDOR),
315a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            glGetString(GL_RENDERER),
316a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            glGetString(GL_VERSION),
317a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            glGetString(GL_EXTENSIONS),
318a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            eglQueryString(display, EGL_VENDOR),
319a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            eglQueryString(display, EGL_VERSION),
320a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            eglQueryString(display, EGL_EXTENSIONS));
3218b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
322a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLint w, h;
323a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglQuerySurface(display, surface, EGL_WIDTH,  &w);
324a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglQuerySurface(display, surface, EGL_HEIGHT, &h);
3258b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
326a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
327a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    glGetIntegerv(GL_MAX_VIEWPORT_DIMS, mMaxViewportDims);
3287303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
329edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
3308b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber    glPixelStorei(GL_PACK_ALIGNMENT, 4);
331edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glEnableClientState(GL_VERTEX_ARRAY);
332edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glShadeModel(GL_FLAT);
333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_DITHER);
334edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_CULL_FACE);
335edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
336a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    struct pack565 {
337a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        inline uint16_t operator() (int r, int g, int b) const {
338a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            return (r<<11)|(g<<5)|b;
339a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        }
340a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    } pack565;
341a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
3429575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    const uint16_t protTexData[] = { pack565(0x03, 0x03, 0x03) };
3439575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glGenTextures(1, &mProtectedTexName);
3449575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glBindTexture(GL_TEXTURE_2D, mProtectedTexName);
3459575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3469575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3479575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
3489575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
3499575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0,
3509575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis            GL_RGB, GL_UNSIGNED_SHORT_5_6_5, protTexData);
351edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
352edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glViewport(0, 0, w, h);
353edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glMatrixMode(GL_PROJECTION);
354edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glLoadIdentity();
355ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    // put the origin in the left-bottom corner
356ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    glOrthof(0, w, 0, h, 0, 1); // l=0, r=w ; b=0, t=h
357edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
358a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // print some debugging info
359a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLint r,g,b,a;
360a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglGetConfigAttrib(display, mEGLConfig, EGL_RED_SIZE,   &r);
361a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglGetConfigAttrib(display, mEGLConfig, EGL_GREEN_SIZE, &g);
362a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglGetConfigAttrib(display, mEGLConfig, EGL_BLUE_SIZE,  &b);
363a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglGetConfigAttrib(display, mEGLConfig, EGL_ALPHA_SIZE, &a);
364a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("EGL informations:");
365a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("vendor    : %s", extensions.getEglVendor());
366a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("version   : %s", extensions.getEglVersion());
367a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("extensions: %s", extensions.getEglExtension());
368a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("Client API: %s", eglQueryString(display, EGL_CLIENT_APIS)?:"Not Supported");
369a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("EGLSurface: %d-%d-%d-%d, config=%p", r, g, b, a, mEGLConfig);
370a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("OpenGL ES informations:");
371a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("vendor    : %s", extensions.getVendor());
372a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("renderer  : %s", extensions.getRenderer());
373a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("version   : %s", extensions.getVersion());
374a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("extensions: %s", extensions.getExtension());
375a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("GL_MAX_TEXTURE_SIZE = %d", mMaxTextureSize);
376a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("GL_MAX_VIEWPORT_DIMS = %d x %d", mMaxViewportDims[0], mMaxViewportDims[1]);
377a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
378a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
379a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianstatus_t SurfaceFlinger::readyToRun()
380a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian{
381a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI(  "SurfaceFlinger's main thread ready to run. "
382a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            "Initializing graphics H/W...");
383a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
384a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // initialize EGL
38534a09ba1efd706323a15633da5044b352988eb5fJesse Hall    mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
38634a09ba1efd706323a15633da5044b352988eb5fJesse Hall    eglInitialize(mEGLDisplay, NULL, NULL);
387a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
388a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // Initialize the main display
389a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // create native window to main display
3901a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    sp<FramebufferSurface> fbs = FramebufferSurface::create();
3911a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    if (fbs == NULL) {
392a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        ALOGE("Display subsystem failed to initialize. check logs. exiting...");
393a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        exit(0);
394a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    }
395a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
396e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    sp<SurfaceTextureClient> stc(new SurfaceTextureClient(
397e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            static_cast<sp<ISurfaceTexture> >(fbs->getBufferQueue())));
3981a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
399a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // initialize the config and context
400a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    int format;
4011a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    ANativeWindow* const anw = stc.get();
4021a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    anw->query(anw, NATIVE_WINDOW_FORMAT, &format);
40334a09ba1efd706323a15633da5044b352988eb5fJesse Hall    mEGLConfig  = selectEGLConfig(mEGLDisplay, format);
40434a09ba1efd706323a15633da5044b352988eb5fJesse Hall    mEGLContext = createGLContext(mEGLDisplay, mEGLConfig);
405a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
406a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // initialize our main display hardware
407e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
408e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    for (size_t i=0 ; i<DisplayDevice::DISPLAY_ID_COUNT ; i++) {
409e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        mDefaultDisplays[i] = new BBinder();
410e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        mCurrentState.displays.add(mDefaultDisplays[i], DisplayDeviceState(i));
411e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
412e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    sp<DisplayDevice> hw = new DisplayDevice(this,
413e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            DisplayDevice::DISPLAY_ID_MAIN, anw, fbs, mEGLConfig);
414e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    mDisplays.add(hw->getDisplayId(), hw);
415a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
416a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    //  initialize OpenGL ES
4174297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    EGLSurface surface = hw->getEGLSurface();
41834a09ba1efd706323a15633da5044b352988eb5fJesse Hall    initializeGL(mEGLDisplay, surface);
419d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
420028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian    // start the EventThread
421028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian    mEventThread = new EventThread(this);
422028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian    mEventQueue.setEventThread(mEventThread);
423028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian
4248630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    // initialize the H/W composer
4258b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    mHwc = new HWComposer(this,
4268b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            *static_cast<HWComposer::EventHandler *>(this),
4278b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            fbs->getFbHal());
42892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian
42992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    // initialize our drawing state
43092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    mDrawingState = mCurrentState;
4318630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
432a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // We're now ready to accept clients...
433d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian    mReadyToRunBarrier.open();
434d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
435a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    // start boot animation
436a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    startBootAnim();
4378b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
438edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
439edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
440edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
441a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopianvoid SurfaceFlinger::startBootAnim() {
442a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // start boot animation
443a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("service.bootanim.exit", "0");
444a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("ctl.start", "bootanim");
445a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian}
446a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian
447a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianuint32_t SurfaceFlinger::getMaxTextureSize() const {
448a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    return mMaxTextureSize;
449a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
450a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
451a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianuint32_t SurfaceFlinger::getMaxViewportDims() const {
452a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    return mMaxViewportDims[0] < mMaxViewportDims[1] ?
453a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            mMaxViewportDims[0] : mMaxViewportDims[1];
454a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
455a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
456edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
457d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
458582270d69db94286a248bd829f1ae6f910d45124Jamie Gennisbool SurfaceFlinger::authenticateSurfaceTexture(
459582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis        const sp<ISurfaceTexture>& surfaceTexture) const {
460134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    Mutex::Autolock _l(mStateLock);
461582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis    sp<IBinder> surfaceTextureBinder(surfaceTexture->asBinder());
462134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
463134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // Check the visible layer list for the ISurface
464134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
465134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    size_t count = currentLayers.size();
466134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    for (size_t i=0 ; i<count ; i++) {
467134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        const sp<LayerBase>& layer(currentLayers[i]);
468134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        sp<LayerBaseClient> lbc(layer->getLayerBaseClient());
469582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis        if (lbc != NULL) {
470582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder();
471582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            if (lbcBinder == surfaceTextureBinder) {
472582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis                return true;
473582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            }
474134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        }
475134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    }
476134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
477134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // Check the layers in the purgatory.  This check is here so that if a
478582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis    // SurfaceTexture gets destroyed before all the clients are done using it,
479582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis    // the error will not be reported as "surface XYZ is not authenticated", but
480134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // will instead fail later on when the client tries to use the surface,
481134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // which should be reported as "surface XYZ returned an -ENODEV".  The
482134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // purgatorized layers are no less authentic than the visible ones, so this
483134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // should not cause any harm.
484134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    size_t purgatorySize =  mLayerPurgatory.size();
485134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    for (size_t i=0 ; i<purgatorySize ; i++) {
486134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
487134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        sp<LayerBaseClient> lbc(layer->getLayerBaseClient());
488582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis        if (lbc != NULL) {
489582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder();
490582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            if (lbcBinder == surfaceTextureBinder) {
491582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis                return true;
492582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            }
493134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        }
494134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    }
495134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
496134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    return false;
497134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis}
498134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
499c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopianstatus_t SurfaceFlinger::getDisplayInfo(DisplayID dpy, DisplayInfo* info) {
5001e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian    // TODO: this is here only for compatibility -- should go away eventually.
5011e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian    if (uint32_t(dpy) >= 1) {
502c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian        return BAD_INDEX;
503c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian    }
5048b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian
5058b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    const HWComposer& hwc(getHwComposer());
5068b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    float xdpi = hwc.getDpiX();
5078b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    float ydpi = hwc.getDpiY();
5088b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian
5098b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    // TODO: Not sure if display density should handled by SF any longer
5108b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    class Density {
5118b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        static int getDensityFromProperty(char const* propName) {
5128b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            char property[PROPERTY_VALUE_MAX];
5138b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            int density = 0;
5148b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            if (property_get(propName, property, NULL) > 0) {
5158b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian                density = atoi(property);
5168b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            }
5178b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            return density;
5188b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        }
5198b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    public:
5208b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        static int getEmuDensity() {
5218b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            return getDensityFromProperty("qemu.sf.lcd_density"); }
5228b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        static int getBuildDensity()  {
5238b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            return getDensityFromProperty("ro.sf.lcd_density"); }
5248b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    };
5258b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    // The density of the device is provided by a build property
5268b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    float density = Density::getBuildDensity() / 160.0f;
5278b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    if (density == 0) {
5288b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        // the build doesn't provide a density -- this is wrong!
5298b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        // use xdpi instead
5308b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        ALOGE("ro.sf.lcd_density must be defined as a build property");
5318b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        density = xdpi / 160.0f;
5328b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    }
5338b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    if (Density::getEmuDensity()) {
5348b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        // if "qemu.sf.lcd_density" is specified, it overrides everything
5358b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        xdpi = ydpi = density = Density::getEmuDensity();
5368b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        density /= 160.0f;
5378b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    }
5388b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian
5394297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    sp<const DisplayDevice> hw(getDefaultDisplayDevice());
5404297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    info->w = hw->getWidth();
5414297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    info->h = hw->getHeight();
5428b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    info->xdpi = xdpi;
5438b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    info->ydpi = ydpi;
5448b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    info->fps = float(1e9 / hwc.getRefreshPeriod());
5458b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    info->density = density;
5464297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    info->orientation = hw->getOrientation();
547888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian    // TODO: this needs to go away (currently needed only by webkit)
5484297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    getPixelFormatInfo(hw->getFormat(), &info->pixelFormatInfo);
549888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian    return NO_ERROR;
550c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian}
551c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian
552d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian// ----------------------------------------------------------------------------
553d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
554d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopiansp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection() {
5558aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian    return mEventThread->createEventConnection();
556bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian}
557bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
5583094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopianvoid SurfaceFlinger::connectDisplay(const sp<ISurfaceTexture> display) {
5593094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    EGLSurface result = EGL_NO_SURFACE;
5603094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    EGLSurface old_surface = EGL_NO_SURFACE;
5613094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    sp<SurfaceTextureClient> stc;
5623094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
5633094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    if (display != NULL) {
5643094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        stc = new SurfaceTextureClient(display);
565d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        result = eglCreateWindowSurface(mEGLDisplay,
566a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian                mEGLConfig, (EGLNativeWindowType)stc.get(), NULL);
5673094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        ALOGE_IF(result == EGL_NO_SURFACE,
5683094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                "eglCreateWindowSurface failed (ISurfaceTexture=%p)",
5693094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                display.get());
5703094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    }
5713094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
5723094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    { // scope for the lock
5733094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        Mutex::Autolock _l(mStateLock);
5743094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        old_surface = mExternalDisplaySurface;
5753094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        mExternalDisplayNativeWindow = stc;
5763094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        mExternalDisplaySurface = result;
5773094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        ALOGD("mExternalDisplaySurface = %p", result);
5783094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    }
5793094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
5803094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    if (old_surface != EGL_NO_SURFACE) {
5813094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        // Note: EGL allows to destroy an object while its current
5823094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        // it will fail to become current next time though.
583d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        eglDestroySurface(mEGLDisplay, old_surface);
5843094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    }
5853094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian}
5863094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
5873094df359d1e6e2ae8ca4e935cc093f563804c96Mathias AgopianEGLSurface SurfaceFlinger::getExternalDisplaySurface() const {
5883094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    Mutex::Autolock _l(mStateLock);
5893094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    return mExternalDisplaySurface;
5903094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian}
5913094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
592edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
59399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
59499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::waitForEvent() {
59599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.waitMessage();
59699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
59799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
59899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalTransaction() {
59999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.invalidate();
60099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
60199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
60299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalLayerUpdate() {
60399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.invalidate();
60499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
60599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
60699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalRefresh() {
60799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.refresh();
60899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
60999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
61099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg,
61199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        nsecs_t reltime, uint32_t flags) {
61299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return mEventQueue.postMessage(msg, reltime);
61399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
61499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
61599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,
61699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        nsecs_t reltime, uint32_t flags) {
61799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    status_t res = mEventQueue.postMessage(msg, reltime);
61899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    if (res == NO_ERROR) {
61999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        msg->wait();
62099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    }
62199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return res;
62299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
623edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
6244fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianbool SurfaceFlinger::threadLoop() {
625edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    waitForEvent();
62699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return true;
62799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
628edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
6298630320433bd15aca239522e54e711ef6372ab07Mathias Agopianvoid SurfaceFlinger::onVSyncReceived(int dpy, nsecs_t timestamp) {
6308630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    mEventThread->onVSyncReceived(dpy, timestamp);
6318630320433bd15aca239522e54e711ef6372ab07Mathias Agopian}
6328630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
6338630320433bd15aca239522e54e711ef6372ab07Mathias Agopianvoid SurfaceFlinger::eventControl(int event, int enabled) {
6348630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    getHwComposer().eventControl(event, enabled);
6358630320433bd15aca239522e54e711ef6372ab07Mathias Agopian}
6368630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
6374fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::onMessageReceived(int32_t what) {
6381c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
63999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    switch (what) {
6404fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    case MessageQueue::INVALIDATE:
6414fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        handleMessageTransaction();
6424fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        handleMessageInvalidate();
6434fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        signalRefresh();
6444fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        break;
6454fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    case MessageQueue::REFRESH:
6464fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        handleMessageRefresh();
6474fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        break;
6484fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
6494fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
650edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
6514fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageTransaction() {
652e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    uint32_t transactionFlags = peekTransactionFlags(eTransactionMask);
6534fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    if (transactionFlags) {
65487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        handleTransaction(transactionFlags);
6554fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
6564fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
657edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
6584fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageInvalidate() {
65987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    handlePageFlip();
6604fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
6613a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian
6624fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageRefresh() {
6634fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    handleRefresh();
664a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
66552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    if (CC_UNLIKELY(mVisibleRegionsDirty)) {
66687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        mVisibleRegionsDirty = false;
66787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        invalidateHwcGeometry();
6683b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
6693b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        /*
6703b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian         *  rebuild the visible layer list per screen
6713b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian         */
6723b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
67387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
67492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
6754297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            const sp<DisplayDevice>& hw(mDisplays[dpy]);
67687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            Region opaqueRegion;
67787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            Region dirtyRegion;
67887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            computeVisibleRegions(currentLayers,
6794297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                    hw->getLayerStack(), dirtyRegion, opaqueRegion);
6804297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->dirtyRegion.orSelf(dirtyRegion);
68187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
68287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            Vector< sp<LayerBase> > layersSortedByZ;
68387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            const size_t count = currentLayers.size();
68487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            for (size_t i=0 ; i<count ; i++) {
68587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian                const Layer::State& s(currentLayers[i]->drawingState());
6864297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                if (s.layerStack == hw->getLayerStack()) {
68787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian                    if (!currentLayers[i]->visibleRegion.isEmpty()) {
68887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian                        layersSortedByZ.add(currentLayers[i]);
68987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian                    }
69087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian                }
6913b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian            }
6924297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->setVisibleLayersSortedByZ(layersSortedByZ);
6934297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->undefinedRegion.set(hw->getBounds());
6944297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->undefinedRegion.subtractSelf(hw->getTransform().transform(opaqueRegion));
6953b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        }
6963b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
6973b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
69852bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    HWComposer& hwc(getHwComposer());
69952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    if (hwc.initCheck() == NO_ERROR) {
70052bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        // build the h/w work list
70152bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        const bool workListsDirty = mHwWorkListDirty;
70252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        mHwWorkListDirty = false;
70392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
7044297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            sp<const DisplayDevice> hw(mDisplays[dpy]);
7054297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            const Vector< sp<LayerBase> >& currentLayers(hw->getVisibleLayersSortedByZ());
70652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            const size_t count = currentLayers.size();
707303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian
7081e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian            const int32_t id = hw->getDisplayId();
7091e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian            if (hwc.createWorkList(id, count) >= 0) {
7101e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                HWComposer::LayerListIterator cur = hwc.begin(id);
7111e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                const HWComposer::LayerListIterator end = hwc.end(id);
7121e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
7131e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                    const sp<LayerBase>& layer(currentLayers[i]);
7141e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian
7151e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                    if (CC_UNLIKELY(workListsDirty)) {
7161e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                        layer->setGeometry(hw, *cur);
7171e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                        if (mDebugDisableHWC || mDebugRegion) {
7181e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                            cur->setSkip(true);
7191e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                        }
72052bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian                    }
72152bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian
7221e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                    /*
7231e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                     * update the per-frame h/w composer data for each layer
7241e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                     * and build the transparent region of the FB
7251e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                     */
7261e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                    layer->setPerFrameData(hw, *cur);
7271e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                }
72852bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            }
72987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        }
73052bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        status_t err = hwc.prepare();
73152bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
73252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    }
73352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian
73452bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    const bool repaintEverything = android_atomic_and(0, &mRepaintEverything);
73592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
7364297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
737303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian
73887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        // transform the dirty region into this screen's coordinate space
7394297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const Transform& planeTransform(hw->getTransform());
74087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        Region dirtyRegion;
74187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        if (repaintEverything) {
7424297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            dirtyRegion.set(hw->bounds());
74352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        } else {
7444297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            dirtyRegion = planeTransform.transform(hw->dirtyRegion);
7454297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            dirtyRegion.andSelf(hw->bounds());
74687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        }
7474297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        hw->dirtyRegion.clear();
748b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian
74952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        if (!dirtyRegion.isEmpty()) {
7504297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            if (hw->canDraw()) {
75152bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian                // repaint the framebuffer (if needed)
75252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian                handleRepaint(hw, dirtyRegion);
75352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            }
75487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        }
75552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        // inform the h/w that we're done compositing
7564297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        hw->compositionComplete();
7574fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
7583094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
75952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    postFramebuffer();
76087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
76152bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian
76252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian#if 1
7634fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    // render to the external display if we have one
7644fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    EGLSurface externalDisplaySurface = getExternalDisplaySurface();
7654fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    if (externalDisplaySurface != EGL_NO_SURFACE) {
7664fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        EGLSurface cur = eglGetCurrentSurface(EGL_DRAW);
7674fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        EGLBoolean success = eglMakeCurrent(eglGetCurrentDisplay(),
7684fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                externalDisplaySurface, externalDisplaySurface,
7694fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                eglGetCurrentContext());
7704fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
7714fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        ALOGE_IF(!success, "eglMakeCurrent -> external failed");
7724fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
7734fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        if (success) {
7744fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            // redraw the screen entirely...
7754fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            glDisable(GL_TEXTURE_EXTERNAL_OES);
7764fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            glDisable(GL_TEXTURE_2D);
7774fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            glClearColor(0,0,0,1);
7784fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            glClear(GL_COLOR_BUFFER_BIT);
7794fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            glMatrixMode(GL_MODELVIEW);
7804fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            glLoadIdentity();
7813b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
7824297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            const sp<DisplayDevice>& hw(getDisplayDevice(0));
7834297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            const Vector< sp<LayerBase> >& layers( hw->getVisibleLayersSortedByZ() );
7844fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const size_t count = layers.size();
7854fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            for (size_t i=0 ; i<count ; ++i) {
7864fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                const sp<LayerBase>& layer(layers[i]);
787fcb239d3dac8bc80f28177f1951611c1d43286ffMathias Agopian                layer->draw(hw);
7884fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            }
7893094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
7904fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            success = eglSwapBuffers(eglGetCurrentDisplay(), externalDisplaySurface);
7914fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            ALOGE_IF(!success, "external display eglSwapBuffers failed");
7923094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
7934297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->compositionComplete();
7944fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        }
7953094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
7964fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        success = eglMakeCurrent(eglGetCurrentDisplay(),
7974fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                cur, cur, eglGetCurrentContext());
7984fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
7994fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        ALOGE_IF(!success, "eglMakeCurrent -> internal failed");
800edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
80187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian#endif
8024fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
803edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
804edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
805edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer()
806edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
807841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
808b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian
809a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    const nsecs_t now = systemTime();
810a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = now;
811c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall
81252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    HWComposer& hwc(getHwComposer());
81352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian
81492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
8154297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
81652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        if (hwc.initCheck() == NO_ERROR) {
8174297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            const Vector< sp<LayerBase> >& currentLayers(hw->getVisibleLayersSortedByZ());
81852bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            const size_t count = currentLayers.size();
8191e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian            const int32_t id = hw->getDisplayId();
8201e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian            HWComposer::LayerListIterator cur = hwc.begin(id);
8211e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian            const HWComposer::LayerListIterator end = hwc.end(id);
82252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
82352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian                const sp<LayerBase>& layer(currentLayers[i]);
824d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian                layer->setAcquireFence(hw, *cur);
825c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall            }
826c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall        }
8274297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        hw->flip(hw->swapRegion);
8284297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        hw->swapRegion.clear();
829c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall    }
830c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall
831ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall    if (hwc.initCheck() == NO_ERROR) {
83252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        // FIXME: eventually commit() won't take arguments
8334297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        hwc.commit(mEGLDisplay, getDefaultDisplayDevice()->getEGLSurface());
83452bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    }
83552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian
83692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
8374297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        sp<const DisplayDevice> hw(mDisplays[dpy]);
8384297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const Vector< sp<LayerBase> >& currentLayers(hw->getVisibleLayersSortedByZ());
83952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        const size_t count = currentLayers.size();
84052bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        if (hwc.initCheck() == NO_ERROR) {
8411e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian            int32_t id = hw->getDisplayId();
8421e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian            HWComposer::LayerListIterator cur = hwc.begin(id);
8431e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian            const HWComposer::LayerListIterator end = hwc.end(id);
84452bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            for (size_t i = 0; cur != end && i < count; ++i, ++cur) {
845d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian                currentLayers[i]->onLayerDisplayed(hw, &*cur);
84652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            }
84752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        } else {
8484297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            eglSwapBuffers(mEGLDisplay, hw->getEGLSurface());
84952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            for (size_t i = 0; i < count; i++) {
850d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian                currentLayers[i]->onLayerDisplayed(hw, NULL);
85152bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            }
852ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall        }
85352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian
85452bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        // FIXME: we need to call eglSwapBuffers() on displays that have GL composition
855e8696a40e09b24b634214684d18526187b316a2fJamie Gennis    }
856e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
857a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mLastSwapBufferTime = systemTime() - now;
858a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = 0;
859edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
860edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
86187baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
862edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
863841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
864841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
865ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    Mutex::Autolock _l(mStateLock);
866ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    const nsecs_t now = systemTime();
867ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = now;
868ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
869ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // Here we're guaranteed that some transaction flags are set
870ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // so we can call handleTransactionLocked() unconditionally.
871ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // We call getTransactionFlags(), which will also clear the flags,
872ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // with mStateLock held to guarantee that mCurrentState won't change
873ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // until the transaction is committed.
874ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
875e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    transactionFlags = getTransactionFlags(eTransactionMask);
87687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    handleTransactionLocked(transactionFlags);
877ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
878ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mLastTransactionTime = systemTime() - now;
879ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = 0;
880ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    invalidateHwcGeometry();
881ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // here the transaction has been committed
8823d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian}
883edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
88487baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
8853d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{
8863d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    const LayerVector& currentLayers(mCurrentState.layersSortedByZ);
887edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t count = currentLayers.size();
888edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
889edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
890edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Traversal of the children
891edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * (perform the transaction for each of them if needed)
892edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
893edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
8943559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    if (transactionFlags & eTraversalNeeded) {
895edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (size_t i=0 ; i<count ; i++) {
896076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            const sp<LayerBase>& layer = currentLayers[i];
897edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
898edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (!trFlags) continue;
899edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
900edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const uint32_t flags = layer->doTransaction(0);
901edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (flags & Layer::eVisibleRegion)
902edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mVisibleRegionsDirty = true;
903edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
904edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
905edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
906edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
9073559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian     * Perform display own transactions if needed
908edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
909edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
910e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    if (transactionFlags & eDisplayTransactionNeeded) {
91192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        // here we take advantage of Vector's copy-on-write semantics to
91292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        // improve performance by skipping the transaction entirely when
91392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        // know that the lists are identical
914e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const KeyedVector<  wp<IBinder>, DisplayDeviceState>& curr(mCurrentState.displays);
915e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const KeyedVector<  wp<IBinder>, DisplayDeviceState>& draw(mDrawingState.displays);
91692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        if (!curr.isIdenticalTo(draw)) {
917edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
91892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            const size_t cc = curr.size();
91992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            const size_t dc = draw.size();
92092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian
92192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // find the displays that were removed
92292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // (ie: in drawing state but not in current state)
92392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // also handle displays that changed
92492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // (ie: displays that are in both lists)
92592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            for (size_t i=0 ; i<dc ; i++) {
926e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                const ssize_t j = curr.indexOfKey(draw.keyAt(i));
927e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                if (j < 0) {
92892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    // in drawing state but not in current state
92992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    if (draw[i].id != DisplayDevice::DISPLAY_ID_MAIN) {
93092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                        mDisplays.removeItem(draw[i].id);
93192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    } else {
93292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                        ALOGW("trying to remove the main display");
93392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    }
93492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                } else {
93592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    // this display is in both lists. see if something changed.
936e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                    const DisplayDeviceState& state(curr[j]);
937e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                    if (state.surface != draw[i].surface) {
938e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        // changing the surface is like destroying and
939e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        // recreating the DisplayDevice
940e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
941e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        sp<SurfaceTextureClient> stc(
942e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                                new SurfaceTextureClient(state.surface));
943e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
944e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        sp<DisplayDevice> disp = new DisplayDevice(this,
945e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                                state.id, stc, 0, mEGLConfig);
946e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
947e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        disp->setLayerStack(state.layerStack);
948e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        disp->setOrientation(state.orientation);
949e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        // TODO: take viewport and frame into account
950e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        mDisplays.replaceValueFor(state.id, disp);
951e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                    }
95292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    if (state.layerStack != draw[i].layerStack) {
9534297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                        const sp<DisplayDevice>& disp(getDisplayDevice(state.id));
95428947d7fbf9f486539322e8e12dd057568e180c2Mathias Agopian                        disp->setLayerStack(state.layerStack);
95592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    }
956e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                    if (state.orientation != draw[i].orientation ||
957e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        state.viewport != draw[i].viewport ||
958e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        state.frame != draw[i].frame) {
9594297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                        const sp<DisplayDevice>& disp(getDisplayDevice(state.id));
9604297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                        disp->setOrientation(state.orientation);
961e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        // TODO: take viewport and frame into account
96292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    }
96392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                }
96492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            }
96592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian
96692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // find displays that were added
96792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // (ie: in current state but not in drawing state)
96892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            for (size_t i=0 ; i<cc ; i++) {
969e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                if (draw.indexOfKey(curr.keyAt(i)) < 0) {
97092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    // FIXME: we need to pass the surface here
971e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                    const DisplayDeviceState& state(curr[i]);
972e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                    sp<SurfaceTextureClient> stc(
973e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                            new SurfaceTextureClient(state.surface));
974e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                    sp<DisplayDevice> disp = new DisplayDevice(this, state.id,
975e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                            stc, 0, mEGLConfig);
976e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                    mDisplays.add(state.id, disp);
97792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                }
97892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            }
979edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
9803559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    }
981edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
9823559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    /*
9833559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian     * Perform our own transaction if needed
9843559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian     */
985edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
9863559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    if (currentLayers.size() > mDrawingState.layersSortedByZ.size()) {
9873559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        // layers have been added
9883559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        mVisibleRegionsDirty = true;
9893559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    }
9903559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian
9913559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    // some layers might have been removed, so
9923559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    // we need to update the regions they're exposing.
9933559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    if (mLayersRemoved) {
9943559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        mLayersRemoved = false;
9953559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        mVisibleRegionsDirty = true;
9963559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        const LayerVector& previousLayers(mDrawingState.layersSortedByZ);
9973559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        const size_t count = previousLayers.size();
9983559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        for (size_t i=0 ; i<count ; i++) {
9993559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian            const sp<LayerBase>& layer(previousLayers[i]);
10003559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian            if (currentLayers.indexOf(layer) < 0) {
10013559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                // this layer is not visible anymore
10023559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                // TODO: we could traverse the tree from front to back and
10033559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                //       compute the actual visible region
10043559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                // TODO: we could cache the transformed region
10053559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                Layer::State front(layer->drawingState());
10063559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                Region visibleReg = front.transform.transform(
10073559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                        Region(Rect(front.active.w, front.active.h)));
10083559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                invalidateLayerStack(front.layerStack, visibleReg);
10090aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            }
1010edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1011edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1012edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1013edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    commitTransaction();
10144fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
10154fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
10164fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::commitTransaction()
10174fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian{
10184fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    if (!mLayersPendingRemoval.isEmpty()) {
10194fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // Notify removed layers now that they can't be drawn from
10204fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        for (size_t i = 0; i < mLayersPendingRemoval.size(); i++) {
10214fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            mLayersPendingRemoval[i]->onRemoved();
10224fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        }
10234fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        mLayersPendingRemoval.clear();
10244fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
10254fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
10264fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mDrawingState = mCurrentState;
10274fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mTransationPending = false;
10284fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mTransactionCV.broadcast();
1029edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1030edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1031edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::computeVisibleRegions(
103287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const LayerVector& currentLayers, uint32_t layerStack,
103387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        Region& outDirtyRegion, Region& outOpaqueRegion)
1034edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1035841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
1036841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
1037edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveOpaqueLayers;
1038edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveCoveredLayers;
1039edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region dirty;
1040edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
104187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    outDirtyRegion.clear();
1042edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1043edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t i = currentLayers.size();
1044edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    while (i--) {
1045076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        const sp<LayerBase>& layer = currentLayers[i];
1046edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1047edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // start with the whole surface at its current location
1048970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian        const Layer::State& s(layer->drawingState());
1049edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
105087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        // only consider the layers on the given later stack
105187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        if (s.layerStack != layerStack)
105287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            continue;
105387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
1054ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
1055ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * opaqueRegion: area of a surface that is fully opaque.
1056ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
1057edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region opaqueRegion;
1058ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1059ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
1060ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visibleRegion: area of a surface that is visible on screen
1061ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * and not fully transparent. This is essentially the layer's
1062ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * footprint minus the opaque regions above it.
1063ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * Areas covered by a translucent surface are considered visible.
1064ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
1065edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region visibleRegion;
1066ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1067ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
1068ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * coveredRegion: area of a surface that is covered by all
1069ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visible regions above it (which includes the translucent areas).
1070ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
1071edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region coveredRegion;
1072ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1073ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1074ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // handle hidden surfaces by setting the visible region to empty
10753165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        if (CC_LIKELY(!(s.flags & layer_state_t::eLayerHidden) && s.alpha)) {
1076a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            const bool translucent = !layer->isOpaque();
10774fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            Rect bounds(layer->computeBounds());
1078edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            visibleRegion.set(bounds);
1079ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            if (!visibleRegion.isEmpty()) {
1080ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // Remove the transparent area from the visible region
1081ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (translucent) {
10824fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    Region transparentRegionScreen;
10834fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    const Transform tr(s.transform);
10844fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    if (tr.transformed()) {
10854fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                        if (tr.preserveRects()) {
10864fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            // transform the transparent region
10874fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            transparentRegionScreen = tr.transform(s.transparentRegion);
10884fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                        } else {
10894fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            // transformation too complex, can't do the
10904fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            // transparent region optimization.
10914fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            transparentRegionScreen.clear();
10924fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                        }
10934fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    } else {
10944fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                        transparentRegionScreen = s.transparentRegion;
10954fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    }
10964fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    visibleRegion.subtractSelf(transparentRegionScreen);
1097ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
1098edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1099ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // compute the opaque region
11004fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                const int32_t layerOrientation = s.transform.getOrientation();
1101ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (s.alpha==255 && !translucent &&
1102ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                        ((layerOrientation & Transform::ROT_INVALID) == false)) {
1103ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    // the opaque region is the layer's footprint
1104ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    opaqueRegion = visibleRegion;
1105ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
1106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1109ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Clip the covered region to the visible region
1110ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        coveredRegion = aboveCoveredLayers.intersect(visibleRegion);
1111ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1112ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveCoveredLayers for next (lower) layer
1113ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        aboveCoveredLayers.orSelf(visibleRegion);
1114ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // subtract the opaque region covered by the layers above us
1116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        visibleRegion.subtractSelf(aboveOpaqueLayers);
1117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // compute this layer's dirty region
1119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (layer->contentDirty) {
1120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // we need to invalidate the whole region
1121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dirty = visibleRegion;
1122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // as well, as the old visible region
11234fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            dirty.orSelf(layer->visibleRegion);
1124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->contentDirty = false;
1125edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
1126a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian            /* compute the exposed region:
1127ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   the exposed region consists of two components:
1128ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   1) what's VISIBLE now and was COVERED before
1129ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   2) what's EXPOSED now less what was EXPOSED before
1130ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
1131ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * note that (1) is conservative, we start with the whole
1132ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * visible region but only keep what used to be covered by
1133ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * something -- which mean it may have been exposed.
1134ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
1135ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * (2) handles areas that were not covered by anything but got
1136ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * exposed because of a resize.
1137a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian             */
1138ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region newExposed = visibleRegion - coveredRegion;
11394fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region oldVisibleRegion = layer->visibleRegion;
11404fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region oldCoveredRegion = layer->coveredRegion;
1141ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldExposed = oldVisibleRegion - oldCoveredRegion;
1142ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed);
1143edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirty.subtractSelf(aboveOpaqueLayers);
1145edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1146edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // accumulate to the screen dirty region
114787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        outDirtyRegion.orSelf(dirty);
1148edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1149ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveOpaqueLayers for next (lower) layer
1150edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        aboveOpaqueLayers.orSelf(opaqueRegion);
11518b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
1152edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // Store the visible region is screen space
1153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setVisibleRegion(visibleRegion);
1154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setCoveredRegion(coveredRegion);
1155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
115787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    outOpaqueRegion = aboveOpaqueLayers;
1158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
116087baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::invalidateLayerStack(uint32_t layerStack,
116187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const Region& dirty) {
116292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
11634297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
11644297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        if (hw->getLayerStack() == layerStack) {
11654297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->dirtyRegion.orSelf(dirty);
116692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        }
116792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    }
116887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian}
116987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
117087baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handlePageFlip()
1171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
11721c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
11734fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    Region dirtyRegion;
117499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
11751bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian    const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
1176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
11774fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    bool visibleRegions = false;
11784fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    const size_t count = currentLayers.size();
11794fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    sp<LayerBase> const* layers = currentLayers.array();
11804fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    for (size_t i=0 ; i<count ; i++) {
11814fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        const sp<LayerBase>& layer(layers[i]);
118287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const Region dirty(layer->latchBuffer(visibleRegions));
118387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        Layer::State s(layer->drawingState());
118487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        invalidateLayerStack(s.layerStack, dirty);
11854fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
11864da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
11873b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    mVisibleRegionsDirty |= visibleRegions;
1188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1190ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopianvoid SurfaceFlinger::invalidateHwcGeometry()
1191ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian{
1192ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian    mHwWorkListDirty = true;
1193ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian}
1194ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian
119599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::handleRefresh()
119699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
119799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    bool needInvalidate = false;
119899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
119999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    const size_t count = currentLayers.size();
120099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
120199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
120299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        if (layer->onPreComposition()) {
120399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            needInvalidate = true;
120499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        }
120599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    }
120699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    if (needInvalidate) {
120799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        signalLayerUpdate();
120899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    }
120999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
121099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
12114297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopianvoid SurfaceFlinger::handleRepaint(const sp<const DisplayDevice>& hw,
121287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const Region& inDirtyRegion)
1213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1214841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
1215841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
121687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    Region dirtyRegion(inDirtyRegion);
121787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
1218b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // compute the invalid region
12194297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->swapRegion.orSelf(dirtyRegion);
1220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
122199ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten    if (CC_UNLIKELY(mDebugRegion)) {
122287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        debugFlashRegions(hw, dirtyRegion);
1223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
12254297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    uint32_t flags = hw->getFlags();
12260f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian    if (flags & DisplayDevice::SWAP_RECTANGLE) {
122729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // we can redraw only what's dirty, but since SWAP_RECTANGLE only
122829d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // takes a rectangle, we must make sure to update that whole
122929d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // rectangle in that case
12304297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        dirtyRegion.set(hw->swapRegion.bounds());
1231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
12320f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian        if (flags & DisplayDevice::PARTIAL_UPDATES) {
123329d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // We need to redraw the rectangle that will be updated
1234df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian            // (pushed to the framebuffer).
123595a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian            // This is needed because PARTIAL_UPDATES only takes one
12360f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian            // rectangle instead of a region (see DisplayDevice::flip())
12374297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            dirtyRegion.set(hw->swapRegion.bounds());
1238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
123929d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // we need to redraw everything (the whole screen)
12404297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            dirtyRegion.set(hw->bounds());
12414297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->swapRegion = dirtyRegion;
1242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
124587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    composeSurfaces(hw, dirtyRegion);
1246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1247d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
1248d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    const size_t count = currentLayers.size();
1249d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
1250d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        currentLayers[i]->onPostComposition();
1251d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    }
1252d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
12539c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    // update the swap region and clear the dirty region
12544297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->swapRegion.orSelf(dirtyRegion);
1255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
12574297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopianvoid SurfaceFlinger::composeSurfaces(const sp<const DisplayDevice>& hw, const Region& dirty)
1258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
12598630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    HWComposer& hwc(getHwComposer());
12601e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian    int32_t id = hw->getDisplayId();
12611e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian    HWComposer::LayerListIterator cur = hwc.begin(id);
12621e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian    const HWComposer::LayerListIterator end = hwc.end(id);
1263a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
12641e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian    const size_t fbLayerCount = hwc.getLayerCount(id, HWC_FRAMEBUFFER);
126552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    if (cur==end || fbLayerCount) {
1266a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
12670f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian        DisplayDevice::makeCurrent(hw, mEGLContext);
1268a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
126952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        // set the frame buffer
127052bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        glMatrixMode(GL_MODELVIEW);
127152bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        glLoadIdentity();
1272a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
1273a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        // Never touch the framebuffer if we don't have any framebuffer layers
12741e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian        if (hwc.getLayerCount(id, HWC_OVERLAY)) {
1275b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // when using overlays, we assume a fully transparent framebuffer
1276b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // NOTE: we could reduce how much we need to clear, for instance
1277b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // remove where there are opaque FB layers. however, on some
1278b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // GPUs doing a "clean slate" glClear might be more efficient.
1279b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // We'll revisit later if needed.
1280b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            glClearColor(0, 0, 0, 0);
1281b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            glClear(GL_COLOR_BUFFER_BIT);
1282b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian        } else {
12834297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            const Region region(hw->undefinedRegion.intersect(dirty));
1284b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // screen is already cleared here
128587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            if (!region.isEmpty()) {
1286b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                // can happen with SurfaceView
128787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian                drawWormhole(region);
1288b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            }
1289a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        }
12904b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian
1291a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        /*
1292a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian         * and then, render the layers targeted at the framebuffer
1293a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian         */
12944b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian
12954297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const Vector< sp<LayerBase> >& layers(hw->getVisibleLayersSortedByZ());
1296a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        const size_t count = layers.size();
12974297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const Transform& tr = hw->getTransform();
1298a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall        for (size_t i=0 ; i<count ; ++i) {
1299a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian            const sp<LayerBase>& layer(layers[i]);
13004fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region clip(dirty.intersect(tr.transform(layer->visibleRegion)));
1301a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian            if (!clip.isEmpty()) {
1302a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall                if (cur != end && cur->getCompositionType() == HWC_OVERLAY) {
13033e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian                    if (i && (cur->getHints() & HWC_HINT_CLEAR_FB)
1304a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                            && layer->isOpaque()) {
1305b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                        // never clear the very first layer since we're
1306b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                        // guaranteed the FB is already cleared
13071b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian                        layer->clearWithOpenGL(hw, clip);
1308a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                    }
13096ee93c0d36dff1339eb2428be2d65441398e6e5fJesse Hall                    ++cur;
1310a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                    continue;
1311a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                }
1312a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                // render the layer
13131b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian                layer->draw(hw, clip);
13144b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian            }
1315a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall            if (cur != end) {
1316a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall                ++cur;
1317a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall            }
13184b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian        }
13194b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian    }
1320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
13224297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopianvoid SurfaceFlinger::debugFlashRegions(const sp<const DisplayDevice>& hw,
132387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const Region& dirtyRegion)
1324edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
13254297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const uint32_t flags = hw->getFlags();
13264297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const int32_t height = hw->getHeight();
13274297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    if (hw->swapRegion.isEmpty()) {
132853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian        return;
132953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian    }
13300a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
13310f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian    if (!(flags & DisplayDevice::SWAP_RECTANGLE)) {
13320f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian        const Region repaint((flags & DisplayDevice::PARTIAL_UPDATES) ?
13334297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                dirtyRegion.bounds() : hw->bounds());
13341b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian        composeSurfaces(hw, repaint);
13350a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    }
13360a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
1337c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_EXTERNAL_OES);
1338c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_2D);
1339edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_BLEND);
1340edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
13410926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    static int toggle = 0;
13420926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    toggle = 1 - toggle;
13430926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    if (toggle) {
13440a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        glColor4f(1, 0, 1, 1);
13450926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    } else {
13460a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        glColor4f(1, 1, 0, 1);
13470926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    }
1348edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
134987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    Region::const_iterator it = dirtyRegion.begin();
135087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    Region::const_iterator const end = dirtyRegion.end();
135120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    while (it != end) {
135220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        const Rect& r = *it++;
1353edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLfloat vertices[][2] = {
135453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.left,  height - r.top },
135553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.left,  height - r.bottom },
135653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.right, height - r.bottom },
135753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.right, height - r.top }
1358edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        };
1359edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glVertexPointer(2, GL_FLOAT, 0, vertices);
1360edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1361edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
13620a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
13634297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->flip(hw->swapRegion);
1364edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1365edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mDebugRegion > 1)
13660a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        usleep(mDebugRegion * 1000);
1367edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1368edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
136987baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::drawWormhole(const Region& region) const
1370edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1371f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    glDisable(GL_TEXTURE_EXTERNAL_OES);
1372b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian    glDisable(GL_TEXTURE_2D);
1373f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    glDisable(GL_BLEND);
1374b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian    glColor4f(0,0,0,0);
1375f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian
1376f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    GLfloat vertices[4][2];
1377f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    glVertexPointer(2, GL_FLOAT, 0, vertices);
1378f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    Region::const_iterator it = region.begin();
1379f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    Region::const_iterator const end = region.end();
1380f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    while (it != end) {
1381f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        const Rect& r = *it++;
1382f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[0][0] = r.left;
1383f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[0][1] = r.top;
1384f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[1][0] = r.right;
1385f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[1][1] = r.top;
1386f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[2][0] = r.right;
1387f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[2][1] = r.bottom;
1388f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[3][0] = r.left;
1389f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[3][1] = r.bottom;
1390f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1391f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    }
1392edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1393edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
139496f0819f81293076e652792794a961543e6750d7Mathias Agopianssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
139596f0819f81293076e652792794a961543e6750d7Mathias Agopian        const sp<LayerBaseClient>& lbc)
13961b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
139796f0819f81293076e652792794a961543e6750d7Mathias Agopian    // attach this layer to the client
13984f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    size_t name = client->attachLayer(lbc);
13994f113740180b6512b43723c4728f262882dc9b45Mathias Agopian
140096f0819f81293076e652792794a961543e6750d7Mathias Agopian    // add this layer to the current state list
1401921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    Mutex::Autolock _l(mStateLock);
1402921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    mCurrentState.layersSortedByZ.add(lbc);
140396f0819f81293076e652792794a961543e6750d7Mathias Agopian
14044f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    return ssize_t(name);
140596f0819f81293076e652792794a961543e6750d7Mathias Agopian}
140696f0819f81293076e652792794a961543e6750d7Mathias Agopian
140796f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer)
140896f0819f81293076e652792794a961543e6750d7Mathias Agopian{
140996f0819f81293076e652792794a961543e6750d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
141096f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = purgatorizeLayer_l(layer);
141196f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR)
14123559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        setTransactionFlags(eTransactionNeeded);
141396f0819f81293076e652792794a961543e6750d7Mathias Agopian    return err;
1414edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1415edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1416076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase)
1417edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1418edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase);
1419edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (index >= 0) {
1420076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved = true;
1421edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
1422edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
14233d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    return status_t(index);
1424edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1425edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
14269a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase)
14279a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
142876cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    // First add the layer to the purgatory list, which makes sure it won't
142976cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    // go away, then remove it from the main list (through a transaction).
14309a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    ssize_t err = removeLayer_l(layerBase);
143176cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    if (err >= 0) {
143276cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian        mLayerPurgatory.add(layerBase);
143376cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    }
14348c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian
14352f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall    mLayersPendingRemoval.push(layerBase);
14360b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian
14373d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // it's possible that we don't find a layer, because it might
14383d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // have been destroyed already -- this is not technically an error
143996f0819f81293076e652792794a961543e6750d7Mathias Agopian    // from the user because there is a race between Client::destroySurface(),
144096f0819f81293076e652792794a961543e6750d7Mathias Agopian    // ~Client() and ~ISurface().
14419a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err;
14429a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
14439a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
1444dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopianuint32_t SurfaceFlinger::peekTransactionFlags(uint32_t flags)
1445dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian{
1446dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian    return android_atomic_release_load(&mTransactionFlags);
1447dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian}
1448dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian
1449edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags)
1450edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1451edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return android_atomic_and(~flags, &mTransactionFlags) & flags;
1452edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1453edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1454bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags)
1455edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1456edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t old = android_atomic_or(flags, &mTransactionFlags);
1457edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((old & flags)==0) { // wake the server up
145899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        signalTransaction();
1459edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1460edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return old;
1461edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1462edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
14638b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopianvoid SurfaceFlinger::setTransactionState(
14648b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        const Vector<ComposerState>& state,
14658b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        const Vector<DisplayState>& displays,
14668b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        uint32_t flags)
14678b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian{
1468698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
146928378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    uint32_t transactionFlags = 0;
1470e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
1471e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    size_t count = displays.size();
1472e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
1473e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const DisplayState& s(displays[i]);
1474e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        transactionFlags |= setDisplayStateLocked(s);
1475b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis    }
1476b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis
1477e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    count = state.size();
1478698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
1479698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const ComposerState& s(state[i]);
1480698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        sp<Client> client( static_cast<Client *>(s.client.get()) );
148128378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        transactionFlags |= setClientStateLocked(client, s.state);
1482698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    }
1483386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian
148428378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    if (transactionFlags) {
1485386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // this triggers the transaction
148628378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        setTransactionFlags(transactionFlags);
1487698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian
1488386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // if this is a synchronous transaction, wait for it to take effect
1489386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // before returning.
1490386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        if (flags & eSynchronous) {
1491386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            mTransationPending = true;
1492386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        }
1493386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        while (mTransationPending) {
1494386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
1495386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            if (CC_UNLIKELY(err != NO_ERROR)) {
1496386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                // just in case something goes wrong in SF, return to the
1497386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                // called after a few seconds.
149832397c1cd3327905173b36baa6fd1c579bc328ffSteve Block                ALOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!");
1499386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                mTransationPending = false;
1500386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                break;
1501386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            }
1502cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        }
1503edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1504edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1505edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1506e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setDisplayStateLocked(const DisplayState& s)
1507e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{
1508e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    uint32_t flags = 0;
1509e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    DisplayDeviceState& disp(mCurrentState.displays.editValueFor(s.token));
1510e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    if (disp.id >= 0) {
1511e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const uint32_t what = s.what;
1512e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & DisplayState::eSurfaceChanged) {
1513e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.surface->asBinder() != s.surface->asBinder()) {
1514e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.surface = s.surface;
1515e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
1516e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1517e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1518e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & DisplayState::eLayerStackChanged) {
1519e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.layerStack != s.layerStack) {
1520e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.layerStack = s.layerStack;
1521e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
1522e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1523e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1524e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & DisplayState::eTransformChanged) {
1525e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.orientation != s.orientation) {
1526e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.orientation = s.orientation;
1527e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
1528e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1529e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.frame != s.frame) {
1530e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.frame = s.frame;
1531e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
1532e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1533e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.viewport != s.viewport) {
1534e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.viewport = s.viewport;
1535e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
1536e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1537e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1538e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
1539e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return flags;
1540e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
1541e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
1542e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setClientStateLocked(
1543e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const sp<Client>& client,
1544e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const layer_state_t& s)
1545e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{
1546e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    uint32_t flags = 0;
1547e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    sp<LayerBaseClient> layer(client->getLayerUser(s.surface));
1548e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    if (layer != 0) {
1549e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const uint32_t what = s.what;
1550e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::ePositionChanged) {
1551e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setPosition(s.x, s.y))
1552e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1553e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1554e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eLayerChanged) {
1555e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            // NOTE: index needs to be calculated before we update the state
1556e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
1557e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setLayer(s.z)) {
1558e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.removeAt(idx);
1559e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.add(layer);
1560e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // we need traversal (state changed)
1561e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // AND transaction (list changed)
1562e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTransactionNeeded|eTraversalNeeded;
1563e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1564e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1565e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eSizeChanged) {
1566e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setSize(s.w, s.h)) {
1567e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1568e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1569e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1570e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eAlphaChanged) {
1571e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f)))
1572e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1573e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1574e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eMatrixChanged) {
1575e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setMatrix(s.matrix))
1576e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1577e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1578e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eTransparentRegionChanged) {
1579e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setTransparentRegionHint(s.transparentRegion))
1580e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1581e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1582e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eVisibilityChanged) {
1583e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setFlags(s.flags, s.mask))
1584e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1585e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1586e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eCropChanged) {
1587e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setCrop(s.crop))
1588e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1589e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1590e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eLayerStackChanged) {
1591e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            // NOTE: index needs to be calculated before we update the state
1592e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
1593e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setLayerStack(s.layerStack)) {
1594e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.removeAt(idx);
1595e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.add(layer);
1596e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // we need traversal (state changed)
1597e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // AND transaction (list changed)
1598e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTransactionNeeded|eTraversalNeeded;
1599e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1600e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1601e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
1602e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return flags;
1603e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
1604e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
1605921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopiansp<ISurface> SurfaceFlinger::createLayer(
16060ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        ISurfaceComposerClient::surface_data_t* params,
16070ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const String8& name,
16080ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const sp<Client>& client,
1609edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        DisplayID d, uint32_t w, uint32_t h, PixelFormat format,
1610edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t flags)
1611edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1612076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBaseClient> layer;
1613a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    sp<ISurface> surfaceHandle;
16146e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian
16156e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    if (int32_t(w|h) < 0) {
1616921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        ALOGE("createLayer() failed, w or h is negative (w=%d, h=%d)",
16176e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian                int(w), int(h));
16186e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian        return surfaceHandle;
16196e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    }
16208b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
1621921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    //ALOGD("createLayer for (%d x %d), name=%s", w, h, name.string());
16223165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian    switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {
16233165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        case ISurfaceComposerClient::eFXSurfaceNormal:
1624921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian            layer = createNormalLayer(client, d, w, h, flags, format);
1625edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
16263165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        case ISurfaceComposerClient::eFXSurfaceBlur:
16273165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        case ISurfaceComposerClient::eFXSurfaceDim:
1628921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian            layer = createDimLayer(client, d, w, h, flags);
1629edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
16303165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        case ISurfaceComposerClient::eFXSurfaceScreenshot:
1631921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian            layer = createScreenshotLayer(client, d, w, h, flags);
1632118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian            break;
1633edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1634edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1635076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (layer != 0) {
163696f0819f81293076e652792794a961543e6750d7Mathias Agopian        layer->initStates(w, h, flags);
1637285dbde2e0cd0057be070ded3be8f5f453147edcMathias Agopian        layer->setName(name);
163896f0819f81293076e652792794a961543e6750d7Mathias Agopian        ssize_t token = addClientLayer(client, layer);
1639edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        surfaceHandle = layer->getSurface();
16408b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber        if (surfaceHandle != 0) {
164196f0819f81293076e652792794a961543e6750d7Mathias Agopian            params->token = token;
1642a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            params->identity = layer->getIdentity();
16431c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        }
164496f0819f81293076e652792794a961543e6750d7Mathias Agopian        setTransactionFlags(eTransactionNeeded);
1645edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1646edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1647edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return surfaceHandle;
1648edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1649edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1650921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopiansp<Layer> SurfaceFlinger::createNormalLayer(
1651f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        const sp<Client>& client, DisplayID display,
165296f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags,
16531c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        PixelFormat& format)
1654edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1655edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize the surfaces
165692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    switch (format) {
1657edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSPARENT:
1658edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSLUCENT:
1659edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        format = PIXEL_FORMAT_RGBA_8888;
1660edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1661edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_OPAQUE:
1662a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888
1663a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian        format = PIXEL_FORMAT_RGB_565;
1664a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#else
16658f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian        format = PIXEL_FORMAT_RGBX_8888;
1666a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif
1667edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1668edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1669edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1670a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888
1671a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian    if (format == PIXEL_FORMAT_RGBX_8888)
1672a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian        format = PIXEL_FORMAT_RGBA_8888;
1673a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif
1674a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian
167596f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<Layer> layer = new Layer(this, display, client);
1676f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian    status_t err = layer->setBuffers(w, h, format, flags);
167799ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten    if (CC_LIKELY(err != NO_ERROR)) {
1678921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        ALOGE("createNormalLayer() failed (%s)", strerror(-err));
1679076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        layer.clear();
1680edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1681edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1682edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1683edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1684921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopiansp<LayerDim> SurfaceFlinger::createDimLayer(
1685f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        const sp<Client>& client, DisplayID display,
168696f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags)
1687edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
168896f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<LayerDim> layer = new LayerDim(this, display, client);
1689118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    return layer;
1690118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
1691118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
1692921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopiansp<LayerScreenshot> SurfaceFlinger::createScreenshotLayer(
1693118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        const sp<Client>& client, DisplayID display,
1694118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags)
1695118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{
1696118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    sp<LayerScreenshot> layer = new LayerScreenshot(this, display, client);
1697edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1698edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1699edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1700921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianstatus_t SurfaceFlinger::onLayerRemoved(const sp<Client>& client, SurfaceID sid)
17019a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
17029a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    /*
17039a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     * called by the window manager, when a surface should be marked for
17049a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     * destruction.
17058b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber     *
17060aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * The surface is removed from the current and drawing lists, but placed
17070aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * in the purgatory queue, so it's not destroyed right-away (we need
17080aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * to wait for all client's references to go away first).
17099a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     */
17109a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
171148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    status_t err = NAME_NOT_FOUND;
17120aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian    Mutex::Autolock _l(mStateLock);
171396f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<LayerBaseClient> layer = client->getLayerUser(sid);
1714b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam
171548d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    if (layer != 0) {
171648d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        err = purgatorizeLayer_l(layer);
171748d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        if (err == NO_ERROR) {
171801eb979243a57bd33f8389aeeade8024dd0258c0Jeff Brown            setTransactionFlags(eDisplayTransactionNeeded);
171948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        }
17209a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    }
17219a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return err;
17229a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
17239a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
1724921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianstatus_t SurfaceFlinger::onLayerDestroyed(const wp<LayerBaseClient>& layer)
1725edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1726759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian    // called by ~ISurface() when all references are gone
1727ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    status_t err = NO_ERROR;
1728ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    sp<LayerBaseClient> l(layer.promote());
1729ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    if (l != NULL) {
1730ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        Mutex::Autolock _l(mStateLock);
1731ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        err = removeLayer_l(l);
1732ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        if (err == NAME_NOT_FOUND) {
1733ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // The surface wasn't in the current list, which means it was
1734ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // removed already, which means it is in the purgatory,
1735ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // and need to be removed from there.
1736ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            ssize_t idx = mLayerPurgatory.remove(l);
1737e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block            ALOGE_IF(idx < 0,
1738ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian                    "layer=%p is not in the purgatory list", l.get());
1739f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        }
1740e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE_IF(err<0 && err != NAME_NOT_FOUND,
1741ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian                "error removing layer=%p (%s)", l.get(), strerror(-err));
1742ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    }
1743ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    return err;
1744edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1745edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1746b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// ---------------------------------------------------------------------------
1747b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
1748b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopianvoid SurfaceFlinger::onScreenAcquired() {
17498e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross    ALOGD("Screen about to return, flinger = %p", this);
17504297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    sp<const DisplayDevice> hw(getDefaultDisplayDevice()); // XXX: this should be per DisplayDevice
17518630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    getHwComposer().acquire();
17524297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->acquireScreen();
175322ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian    mEventThread->onScreenAcquired();
175420128300e0cb7f459a60cfbcddb48190ce6545edMathias Agopian    mVisibleRegionsDirty = true;
175520128300e0cb7f459a60cfbcddb48190ce6545edMathias Agopian    repaintEverything();
1756edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1757edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1758b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopianvoid SurfaceFlinger::onScreenReleased() {
17598e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross    ALOGD("About to give-up screen, flinger = %p", this);
17604297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    sp<const DisplayDevice> hw(getDefaultDisplayDevice()); // XXX: this should be per DisplayDevice
17614297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    if (hw->isScreenAcquired()) {
176222ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian        mEventThread->onScreenReleased();
17634297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        hw->releaseScreen();
17648630320433bd15aca239522e54e711ef6372ab07Mathias Agopian        getHwComposer().release();
1765b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        // from this point on, SF will stop drawing
1766b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    }
1767b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian}
1768b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
17698e533069e5721e55cb9768e140e16546c3a4a8b6Colin Crossvoid SurfaceFlinger::unblank() {
1770b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    class MessageScreenAcquired : public MessageBase {
1771b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        SurfaceFlinger* flinger;
1772b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    public:
1773b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        MessageScreenAcquired(SurfaceFlinger* flinger) : flinger(flinger) { }
1774b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        virtual bool handler() {
1775b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            flinger->onScreenAcquired();
1776b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            return true;
1777b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        }
1778b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    };
1779b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    sp<MessageBase> msg = new MessageScreenAcquired(this);
1780b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    postMessageSync(msg);
1781edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1782edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
17838e533069e5721e55cb9768e140e16546c3a4a8b6Colin Crossvoid SurfaceFlinger::blank() {
1784b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    class MessageScreenReleased : public MessageBase {
1785b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        SurfaceFlinger* flinger;
1786b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    public:
1787b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        MessageScreenReleased(SurfaceFlinger* flinger) : flinger(flinger) { }
1788b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        virtual bool handler() {
1789b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            flinger->onScreenReleased();
1790b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            return true;
1791b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        }
1792b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    };
1793b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    sp<MessageBase> msg = new MessageScreenReleased(this);
1794b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    postMessageSync(msg);
1795b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian}
1796b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
1797b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// ---------------------------------------------------------------------------
1798b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
1799edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
1800edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
18011d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling    const size_t SIZE = 4096;
1802edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char buffer[SIZE];
1803edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    String8 result;
180499b49840d309727678b77403d6cc9f920111623fMathias Agopian
180599b49840d309727678b77403d6cc9f920111623fMathias Agopian    if (!PermissionCache::checkCallingPermission(sDump)) {
1806edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        snprintf(buffer, SIZE, "Permission Denial: "
1807edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                "can't dump SurfaceFlinger from pid=%d, uid=%d\n",
1808edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                IPCThreadState::self()->getCallingPid(),
1809edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                IPCThreadState::self()->getCallingUid());
1810edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        result.append(buffer);
1811edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
18129795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // Try to get the main lock, but don't insist if we can't
18139795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // (this would indicate SF is stuck, but we want to be able to
18149795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // print something in dumpsys).
18159795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        int retry = 3;
18169795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        while (mStateLock.tryLock()<0 && --retry>=0) {
18179795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            usleep(1000000);
18189795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
18199795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const bool locked(retry >= 0);
18209795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (!locked) {
18218b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber            snprintf(buffer, SIZE,
18229795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "SurfaceFlinger appears to be unresponsive, "
18239795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "dumping anyways (no locks held)\n");
18249795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            result.append(buffer);
18259795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
18269795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
182782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        bool dumpAll = true;
182882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        size_t index = 0;
182925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        size_t numArgs = args.size();
183025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        if (numArgs) {
183125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
183225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--list"))) {
183325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                index++;
183425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                listLayersLocked(args, index, result, buffer, SIZE);
183535aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
183625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            }
183725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
183825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
183925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--latency"))) {
184082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                index++;
184182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                dumpStatsLocked(args, index, result, buffer, SIZE);
184235aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
184382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            }
184425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
184525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
184625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--latency-clear"))) {
184725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                index++;
184825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                clearStatsLocked(args, index, result, buffer, SIZE);
184935aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
185025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            }
1851edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
18521b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
185382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (dumpAll) {
185482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            dumpAllLocked(result, buffer, SIZE);
185582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
185648b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
185782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (locked) {
185882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mStateLock.unlock();
185948b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        }
186082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
186182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    write(fd, result.string(), result.size());
186282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    return NO_ERROR;
186382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
186448b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
186525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::listLayersLocked(const Vector<String16>& args, size_t& index,
186625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        String8& result, char* buffer, size_t SIZE) const
186725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
186825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
186925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const size_t count = currentLayers.size();
187025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
187125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
187225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        snprintf(buffer, SIZE, "%s\n", layer->getName().string());
187325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        result.append(buffer);
187425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
187525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
187625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
187782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index,
187882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        String8& result, char* buffer, size_t SIZE) const
187982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
188082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    String8 name;
188182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    if (index < args.size()) {
188282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        name = String8(args[index]);
188382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        index++;
188482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
188548b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
188682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
188782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const size_t count = currentLayers.size();
188882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    for (size_t i=0 ; i<count ; i++) {
188982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
189082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (name.isEmpty()) {
189182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            snprintf(buffer, SIZE, "%s\n", layer->getName().string());
189282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            result.append(buffer);
189382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
189482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (name.isEmpty() || (name == layer->getName())) {
189582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            layer->dumpStats(result, buffer, SIZE);
189682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
189782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
189882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
1899ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian
190025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& index,
190125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        String8& result, char* buffer, size_t SIZE) const
190225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
190325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    String8 name;
190425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    if (index < args.size()) {
190525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        name = String8(args[index]);
190625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        index++;
190725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
190825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
190925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
191025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const size_t count = currentLayers.size();
191125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
191225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
191325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        if (name.isEmpty() || (name == layer->getName())) {
191425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            layer->clearStats();
191525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        }
191625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
191725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
191825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
191982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpAllLocked(
192082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        String8& result, char* buffer, size_t SIZE) const
192182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
192282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    // figure out if we're stuck somewhere
192382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t now = systemTime();
192482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t inSwapBuffers(mDebugInSwapBuffers);
192582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t inTransaction(mDebugInTransaction);
192682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0;
192782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0;
1928bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
192982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
193082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump the visible layer list
193182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
193282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
193382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const size_t count = currentLayers.size();
193482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "Visible layers (count = %d)\n", count);
193582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
193682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    for (size_t i=0 ; i<count ; i++) {
193782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
193882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        layer->dump(result, buffer, SIZE);
193982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
1940bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
194182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
194282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump the layers in the purgatory
194382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
1944ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian
194582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const size_t purgatorySize = mLayerPurgatory.size();
194682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "Purgatory state (%d entries)\n", purgatorySize);
194782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
194882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    for (size_t i=0 ; i<purgatorySize ; i++) {
194982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
195082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        layer->shortDump(result, buffer, SIZE);
195182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
19521b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
195382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
195482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump SurfaceFlinger global state
195582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
19561b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
195782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "SurfaceFlinger global state:\n");
195882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
19591b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
1960888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian    HWComposer& hwc(getHwComposer());
19614297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    sp<const DisplayDevice> hw(getDefaultDisplayDevice());
196282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const GLExtensions& extensions(GLExtensions::getInstance());
196382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "GLES: %s, %s, %s\n",
196482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            extensions.getVendor(),
196582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            extensions.getRenderer(),
196682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            extensions.getVersion());
196782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
1968d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
196982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "EGL : %s\n",
1970d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian            eglQueryString(mEGLDisplay, EGL_VERSION_HW_ANDROID));
197182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
197273d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian
197382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "EXTS: %s\n", extensions.getExtension());
197482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
19759795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
19764297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->undefinedRegion.dump(result, "undefinedRegion");
197782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE,
197882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  orientation=%d, canDraw=%d\n",
19794297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->getOrientation(), hw->canDraw());
198082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
198182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE,
198282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  last eglSwapBuffers() time: %f us\n"
198382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  last transaction time     : %f us\n"
1984c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian            "  transaction-flags         : %08x\n"
198582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  refresh-rate              : %f fps\n"
198682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  x-dpi                     : %f\n"
19878b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            "  y-dpi                     : %f\n",
198882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mLastSwapBufferTime/1000.0,
198982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mLastTransactionTime/1000.0,
1990c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian            mTransactionFlags,
1991888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian            1e9 / hwc.getRefreshPeriod(),
19928b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            hwc.getDpiX(),
19938b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            hwc.getDpiY());
199482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
199582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
199682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "  eglSwapBuffers time: %f us\n",
199782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            inSwapBuffersDuration/1000.0);
199882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
199982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
200082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "  transaction time: %f us\n",
200182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            inTransactionDuration/1000.0);
200282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
200382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
200482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
200582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * VSYNC state
200682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
200782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    mEventThread->dump(result, buffer, SIZE);
200882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
200982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
201082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump HWComposer state
201182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
201282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "h/w composer state:\n");
201382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
201482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "  h/w composer %s and %s\n",
201582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            hwc.initCheck()==NO_ERROR ? "present" : "not present",
201682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                    (mDebugDisableHWC || mDebugRegion) ? "disabled" : "enabled");
201782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
20184297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hwc.dump(result, buffer, SIZE, hw->getVisibleLayersSortedByZ());
201982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
202082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
202182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump gralloc state
202282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
202382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
202482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    alloc.dump(result);
20254297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->dump(result);
2026edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2027edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2028edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::onTransact(
2029edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
2030edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2031edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (code) {
2032edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case CREATE_CONNECTION:
2033698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        case SET_TRANSACTION_STATE:
2034edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case BOOT_FINISHED:
20358e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross        case BLANK:
20368e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross        case UNBLANK:
2037edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        {
2038edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // codes that require permission check
2039edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            IPCThreadState* ipc = IPCThreadState::self();
2040edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int pid = ipc->getCallingPid();
2041a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian            const int uid = ipc->getCallingUid();
204299b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
204399b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) {
2044e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block                ALOGE("Permission Denial: "
2045375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                        "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
2046375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                return PERMISSION_DENIED;
2047edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
20481b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
20491b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
20501b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        case CAPTURE_SCREEN:
20511b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
20521b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            // codes that require permission check
20531b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
20541b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int pid = ipc->getCallingPid();
20551b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int uid = ipc->getCallingUid();
205699b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
205799b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) {
2058e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block                ALOGE("Permission Denial: "
20591b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                        "can't read framebuffer pid=%d, uid=%d", pid, uid);
20601b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                return PERMISSION_DENIED;
20611b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            }
20621b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
2063edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
2064edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
20651b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
2066edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
2067edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
2068b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        CHECK_INTERFACE(ISurfaceComposer, data, reply);
206999ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten        if (CC_UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) {
2070375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
2071375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int pid = ipc->getCallingPid();
2072375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int uid = ipc->getCallingUid();
2073e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block            ALOGE("Permission Denial: "
2074375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                    "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
2075edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return PERMISSION_DENIED;
2076edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
2077edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int n;
2078edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        switch (code) {
207901b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian            case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE
208035b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian            case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE
2081edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
2082edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1002:  // SHOW_UPDATES
2083edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                n = data.readInt32();
2084edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDebugRegion = n ? n : (mDebugRegion ? 0 : 1);
208553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
208653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
2087edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
2088edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1004:{ // repaint everything
208953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
2090cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
2091cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            }
2092cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            case 1005:{ // force transaction
2093e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                setTransactionFlags(
2094e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        eTransactionNeeded|
2095e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        eDisplayTransactionNeeded|
2096e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        eTraversalNeeded);
2097cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
2098edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
20994d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            case 1006:{ // send empty update
21004d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian                signalRefresh();
21014d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian                return NO_ERROR;
21024d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            }
210353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian            case 1008:  // toggle use of hw composer
210453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                n = data.readInt32();
210553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                mDebugDisableHWC = n ? 1 : 0;
210653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
210753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
210853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                return NO_ERROR;
2109a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian            case 1009:  // toggle use of transform hint
2110a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                n = data.readInt32();
2111a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                mDebugDisableTransformHint = n ? 1 : 0;
2112a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                invalidateHwcGeometry();
2113a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                repaintEverything();
2114a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                return NO_ERROR;
2115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1010:  // interrogate.
211601b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian                reply->writeInt32(0);
2117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(0);
2118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(mDebugRegion);
2119b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                reply->writeInt32(0);
212012839bee29bdcc65731b4d42029cc59e2320c5c4Dianne Hackborn                reply->writeInt32(mDebugDisableHWC);
2121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
2122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1013: {
2123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                Mutex::Autolock _l(mStateLock);
21244297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                sp<const DisplayDevice> hw(getDefaultDisplayDevice());
21254297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                reply->writeInt32(hw->getPageFlipCount());
2126edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
2127edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return NO_ERROR;
2128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
2129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return err;
2131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
213353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopianvoid SurfaceFlinger::repaintEverything() {
213487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    android_atomic_or(1, &mRepaintEverything);
213599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    signalTransaction();
213653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian}
213753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian
213859119e658a12279e8fff508f8773843de2d90917Mathias Agopian// ---------------------------------------------------------------------------
213959119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2140118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopianstatus_t SurfaceFlinger::renderScreenToTexture(DisplayID dpy,
2141118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        GLuint* textureName, GLfloat* uOut, GLfloat* vOut)
2142118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{
2143118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    Mutex::Autolock _l(mStateLock);
2144118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    return renderScreenToTextureLocked(dpy, textureName, uOut, vOut);
2145118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
2146118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
21479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::renderScreenToTextureLocked(DisplayID dpy,
21489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        GLuint* textureName, GLfloat* uOut, GLfloat* vOut)
214959119e658a12279e8fff508f8773843de2d90917Mathias Agopian{
215022ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian    ATRACE_CALL();
215122ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian
215259119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
215359119e658a12279e8fff508f8773843de2d90917Mathias Agopian        return INVALID_OPERATION;
215459119e658a12279e8fff508f8773843de2d90917Mathias Agopian
215559119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // get screen geometry
21564297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    sp<const DisplayDevice> hw(getDisplayDevice(dpy));
21574297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const uint32_t hw_w = hw->getWidth();
21584297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const uint32_t hw_h = hw->getHeight();
215959119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLfloat u = 1;
216059119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLfloat v = 1;
216159119e658a12279e8fff508f8773843de2d90917Mathias Agopian
216259119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // make sure to clear all GL error flags
216359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    while ( glGetError() != GL_NO_ERROR ) ;
216459119e658a12279e8fff508f8773843de2d90917Mathias Agopian
216559119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // create a FBO
216659119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLuint name, tname;
216759119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glGenTextures(1, &tname);
216859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
2169a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2170a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
21719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
21729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            hw_w, hw_h, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
217359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (glGetError() != GL_NO_ERROR) {
2174015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian        while ( glGetError() != GL_NO_ERROR ) ;
217559119e658a12279e8fff508f8773843de2d90917Mathias Agopian        GLint tw = (2 << (31 - clz(hw_w)));
217659119e658a12279e8fff508f8773843de2d90917Mathias Agopian        GLint th = (2 << (31 - clz(hw_h)));
21779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
21789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian                tw, th, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
217959119e658a12279e8fff508f8773843de2d90917Mathias Agopian        u = GLfloat(hw_w) / tw;
218059119e658a12279e8fff508f8773843de2d90917Mathias Agopian        v = GLfloat(hw_h) / th;
218159119e658a12279e8fff508f8773843de2d90917Mathias Agopian    }
218259119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glGenFramebuffersOES(1, &name);
218359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
21849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES,
21859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0);
218659119e658a12279e8fff508f8773843de2d90917Mathias Agopian
21879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // redraw the screen entirely...
2188c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_EXTERNAL_OES);
2189c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_2D);
21909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glClearColor(0,0,0,1);
21919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glClear(GL_COLOR_BUFFER_BIT);
2192a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glMatrixMode(GL_MODELVIEW);
2193a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glLoadIdentity();
21944297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const Vector< sp<LayerBase> >& layers(hw->getVisibleLayersSortedByZ());
21959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const size_t count = layers.size();
21969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (size_t i=0 ; i<count ; ++i) {
21979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
2198fcb239d3dac8bc80f28177f1951611c1d43286ffMathias Agopian        layer->draw(hw);
21999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
220059119e658a12279e8fff508f8773843de2d90917Mathias Agopian
22014297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->compositionComplete();
2202118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
22039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // back to main framebuffer
22049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
22059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDeleteFramebuffersOES(1, &name);
220659119e658a12279e8fff508f8773843de2d90917Mathias Agopian
22079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *textureName = tname;
22089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *uOut = u;
22099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *vOut = v;
22109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
22119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
221259119e658a12279e8fff508f8773843de2d90917Mathias Agopian
22139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// ---------------------------------------------------------------------------
22149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
221574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopianstatus_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy,
221674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        sp<IMemoryHeap>* heap,
221774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t* w, uint32_t* h, PixelFormat* f,
2218bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t sw, uint32_t sh,
2219bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ, uint32_t maxLayerZ)
222074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{
2221fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian    ATRACE_CALL();
2222fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian
222374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    status_t result = PERMISSION_DENIED;
222474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
222574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // only one display supported for now
22263b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    if (CC_UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) {
2227ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian        ALOGE("invalid display %d", dpy);
222874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return BAD_VALUE;
22293b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
223074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
22313b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject()) {
223274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return INVALID_OPERATION;
22333b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
223474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
223574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // get screen geometry
22364297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    sp<const DisplayDevice> hw(getDisplayDevice(dpy));
22374297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const uint32_t hw_w = hw->getWidth();
22384297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const uint32_t hw_h = hw->getHeight();
223974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
22403b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    // if we have secure windows on this display, never allow the screen capture
22414297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    if (hw->getSecureLayerVisible()) {
2242ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian        ALOGW("FB is protected: PERMISSION_DENIED");
22433b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        return PERMISSION_DENIED;
22443b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
22453b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
22463b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    if ((sw > hw_w) || (sh > hw_h)) {
2247ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian        ALOGE("size mismatch (%d, %d) > (%d, %d)", sw, sh, hw_w, hw_h);
224874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return BAD_VALUE;
22493b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
225074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
225174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    sw = (!sw) ? hw_w : sw;
225274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    sh = (!sh) ? hw_h : sh;
225374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const size_t size = sw * sh * 4;
2254fcb239d3dac8bc80f28177f1951611c1d43286ffMathias Agopian    const bool filtering = sw != hw_w || sh != hw_h;
225574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
2256ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian//    ALOGD("screenshot: sw=%d, sh=%d, minZ=%d, maxZ=%d",
2257ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian//            sw, sh, minLayerZ, maxLayerZ);
2258c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
225974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // make sure to clear all GL error flags
226074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    while ( glGetError() != GL_NO_ERROR ) ;
226174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
226274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // create a FBO
226374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    GLuint name, tname;
226474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glGenRenderbuffersOES(1, &tname);
226574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindRenderbufferOES(GL_RENDERBUFFER_OES, tname);
226674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA8_OES, sw, sh);
2267fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian
226874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glGenFramebuffersOES(1, &name);
226974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
227074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES,
227174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, tname);
227274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
227374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
2274c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
227574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    if (status == GL_FRAMEBUFFER_COMPLETE_OES) {
227674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
227774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // invert everything, b/c glReadPixel() below will invert the FB
227874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glViewport(0, 0, sw, sh);
227974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_PROJECTION);
228074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glPushMatrix();
228174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glLoadIdentity();
2282ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian        glOrthof(0, hw_w, hw_h, 0, 0, 1);
228374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_MODELVIEW);
228474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
228574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // redraw the screen entirely...
228674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glClearColor(0,0,0,1);
228774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
2288f653b897a449e10d6cbfb6e0812f7b0bb02d6482Mathias Agopian
22899575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        const LayerVector& layers(mDrawingState.layersSortedByZ);
22909575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        const size_t count = layers.size();
229174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        for (size_t i=0 ; i<count ; ++i) {
229274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            const sp<LayerBase>& layer(layers[i]);
2293b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian            const uint32_t flags = layer->drawingState().flags;
22943165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian            if (!(flags & layer_state_t::eLayerHidden)) {
2295b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                const uint32_t z = layer->drawingState().z;
2296b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                if (z >= minLayerZ && z <= maxLayerZ) {
2297fcb239d3dac8bc80f28177f1951611c1d43286ffMathias Agopian                    if (filtering) layer->setFiltering(true);
2298fcb239d3dac8bc80f28177f1951611c1d43286ffMathias Agopian                    layer->draw(hw);
2299fcb239d3dac8bc80f28177f1951611c1d43286ffMathias Agopian                    if (filtering) layer->setFiltering(false);
2300b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                }
2301bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian            }
230274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        }
230374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
230474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // check for errors and return screen capture
230574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        if (glGetError() != GL_NO_ERROR) {
230674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // error while rendering
230774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            result = INVALID_OPERATION;
230874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        } else {
230974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // allocate shared memory large enough to hold the
231074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // screen capture
231174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            sp<MemoryHeapBase> base(
231274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    new MemoryHeapBase(size, 0, "screen-capture") );
231374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            void* const ptr = base->getBase();
231474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            if (ptr) {
231574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                // capture the screen with glReadPixels()
2316fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian                ScopedTrace _t(ATRACE_TAG, "glReadPixels");
231774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                glReadPixels(0, 0, sw, sh, GL_RGBA, GL_UNSIGNED_BYTE, ptr);
231874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                if (glGetError() == GL_NO_ERROR) {
231974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *heap = base;
232074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *w = sw;
232174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *h = sh;
232274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *f = PIXEL_FORMAT_RGBA_8888;
232374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    result = NO_ERROR;
232474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                }
232574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            } else {
232674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                result = NO_MEMORY;
232774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            }
232874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        }
232974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glViewport(0, 0, hw_w, hw_h);
233074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_PROJECTION);
233174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glPopMatrix();
233274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_MODELVIEW);
233374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    } else {
233474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        result = BAD_VALUE;
233574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    }
233674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
233774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // release FBO resources
233874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
233974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glDeleteRenderbuffersOES(1, &tname);
234074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glDeleteFramebuffersOES(1, &name);
2341e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian
23424297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->compositionComplete();
2343e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian
2344ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian//    ALOGD("screenshot: result = %s", result<0 ? strerror(result) : "OK");
2345c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
234674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    return result;
234774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian}
234874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
234974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
23501b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopianstatus_t SurfaceFlinger::captureScreen(DisplayID dpy,
23511b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        sp<IMemoryHeap>* heap,
235274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t* width, uint32_t* height, PixelFormat* format,
2353bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t sw, uint32_t sh,
2354bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ, uint32_t maxLayerZ)
23551b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian{
23561b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    // only one display supported for now
235799ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten    if (CC_UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
23581b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        return BAD_VALUE;
23591b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
23601b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
23611b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        return INVALID_OPERATION;
23621b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
23631b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    class MessageCaptureScreen : public MessageBase {
23641b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        SurfaceFlinger* flinger;
23651b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        DisplayID dpy;
23661b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        sp<IMemoryHeap>* heap;
23671b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        uint32_t* w;
23681b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        uint32_t* h;
23691b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        PixelFormat* f;
237074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t sw;
237174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t sh;
2372bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ;
2373bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t maxLayerZ;
23741b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        status_t result;
23751b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    public:
23761b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        MessageCaptureScreen(SurfaceFlinger* flinger, DisplayID dpy,
237774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                sp<IMemoryHeap>* heap, uint32_t* w, uint32_t* h, PixelFormat* f,
2378bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                uint32_t sw, uint32_t sh,
2379bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                uint32_t minLayerZ, uint32_t maxLayerZ)
23801b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            : flinger(flinger), dpy(dpy),
2381bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              heap(heap), w(w), h(h), f(f), sw(sw), sh(sh),
2382bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              minLayerZ(minLayerZ), maxLayerZ(maxLayerZ),
2383bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              result(PERMISSION_DENIED)
23841b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
23851b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
23861b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        status_t getResult() const {
23871b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            return result;
23881b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
23891b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        virtual bool handler() {
23901b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
239174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            result = flinger->captureScreenImplLocked(dpy,
2392bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                    heap, w, h, f, sw, sh, minLayerZ, maxLayerZ);
23931b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            return true;
23941b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
23951b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    };
23961b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
23971b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    sp<MessageBase> msg = new MessageCaptureScreen(this,
2398bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian            dpy, heap, width, height, format, sw, sh, minLayerZ, maxLayerZ);
23991b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    status_t res = postMessageSync(msg);
24001b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    if (res == NO_ERROR) {
24011b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        res = static_cast<MessageCaptureScreen*>( msg.get() )->getResult();
24021b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    }
24031b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    return res;
24041b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian}
24051b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
24061b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// ---------------------------------------------------------------------------
24071b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
2408921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::LayerVector::LayerVector() {
2409921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
2410921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
2411921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::LayerVector::LayerVector(const LayerVector& rhs)
2412921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    : SortedVector<sp<LayerBase> >(rhs) {
2413921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
2414921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
2415921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianint SurfaceFlinger::LayerVector::do_compare(const void* lhs,
2416921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    const void* rhs) const
2417edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2418be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    // sort layers per layer-stack, then by z-order and finally by sequence
2419921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    const sp<LayerBase>& l(*reinterpret_cast<const sp<LayerBase>*>(lhs));
2420921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    const sp<LayerBase>& r(*reinterpret_cast<const sp<LayerBase>*>(rhs));
2421be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian
2422be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    uint32_t ls = l->currentState().layerStack;
2423be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    uint32_t rs = r->currentState().layerStack;
2424be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    if (ls != rs)
2425be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian        return ls - rs;
2426be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian
2427921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    uint32_t lz = l->currentState().z;
2428921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    uint32_t rz = r->currentState().z;
2429be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    if (lz != rz)
2430be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian        return lz - rz;
2431be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian
2432be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    return l->sequence - r->sequence;
2433921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
2434921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
2435921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian// ---------------------------------------------------------------------------
2436921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
2437e57f292595bec48f65c8088b00ff6beea01217e9Mathias AgopianSurfaceFlinger::DisplayDeviceState::DisplayDeviceState() : id(-1) {
2438e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
2439e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
2440e57f292595bec48f65c8088b00ff6beea01217e9Mathias AgopianSurfaceFlinger::DisplayDeviceState::DisplayDeviceState(int32_t id)
2441e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    : id(id), layerStack(0), orientation(0) {
2442b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
24437303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
2444b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// ---------------------------------------------------------------------------
244596f0819f81293076e652792794a961543e6750d7Mathias Agopian
24469a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::GraphicBufferAlloc() {}
24479a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
24489a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::~GraphicBufferAlloc() {}
24499a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
24509a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h,
2451d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        PixelFormat format, uint32_t usage, status_t* error) {
24529a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(w, h, format, usage));
24539a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    status_t err = graphicBuffer->initCheck();
2454d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian    *error = err;
2455a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (err != 0 || graphicBuffer->handle == 0) {
2456d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        if (err == NO_MEMORY) {
2457d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian            GraphicBuffer::dumpAllocationsToSystemLog();
2458d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        }
2459e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE("GraphicBufferAlloc::createGraphicBuffer(w=%d, h=%d) "
2460a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian             "failed (%s), handle=%p",
2461a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                w, h, strerror(-err), graphicBuffer->handle);
24629a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis        return 0;
24639a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    }
24649a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    return graphicBuffer;
24659a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis}
24669a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
24679a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis// ---------------------------------------------------------------------------
24689a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
2469edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
2470