SurfaceFlinger.cpp revision da27af9832a0170f1fc40ef3f21371c4d30d21b3
1edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/*
2edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
3edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
4edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * you may not use this file except in compliance with the License.
6edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * You may obtain a copy of the License at
7edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
8edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
10edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * See the License for the specific language governing permissions and
14edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * limitations under the License.
15edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */
16edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
171c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#define ATRACE_TAG ATRACE_TAG_GRAPHICS
181c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
19edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdint.h>
20921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <sys/types.h>
21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <errno.h>
22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <math.h>
2363f165fd6b86d04be94d4023e845e98560504a96Keun young Park#include <dlfcn.h>
24921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
25921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <EGL/egl.h>
26921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <GLES/gl.h>
27edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
28edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/log.h>
29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/properties.h>
30edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
31c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IPCThreadState.h>
32c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IServiceManager.h>
337303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian#include <binder/MemoryHeapBase.h>
3499b49840d309727678b77403d6cc9f920111623fMathias Agopian#include <binder/PermissionCache.h>
357303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
36c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian#include <ui/DisplayInfo.h>
37c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian
38921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <gui/BitTube.h>
391a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <gui/BufferQueue.h>
401a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <gui/IDisplayEventConnection.h>
41921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <gui/SurfaceTextureClient.h>
42921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
43921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <ui/GraphicBufferAllocator.h>
44921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <ui/PixelFormat.h>
45d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
46cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian#include <utils/misc.h>
47edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String8.h>
48edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String16.h>
49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/StopWatch.h>
501c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#include <utils/Trace.h>
51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
52921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <private/android_filesystem_config.h>
53edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h"
5590ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include "DdmConnection.h"
560f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian#include "DisplayDevice.h"
57db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian#include "Client.h"
58d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian#include "EventThread.h"
591f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian#include "GLExtensions.h"
60edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h"
61edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerDim.h"
62118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian#include "LayerScreenshot.h"
63edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h"
64edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
65a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#include "DisplayHardware/FramebufferSurface.h"
66a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian#include "DisplayHardware/HWComposer.h"
67edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
68a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
69bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian#define EGL_VERSION_HW_ANDROID  0x3143
70bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DISPLAY_COUNT       1
72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
73edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
74edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
75edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
7699b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sHardwareTest("android.permission.HARDWARE_TEST");
7799b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER");
7899b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER");
7999b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sDump("android.permission.DUMP");
8099b49840d309727678b77403d6cc9f920111623fMathias Agopian
8199b49840d309727678b77403d6cc9f920111623fMathias Agopian// ---------------------------------------------------------------------------
8299b49840d309727678b77403d6cc9f920111623fMathias Agopian
83edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::SurfaceFlinger()
84edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    :   BnSurfaceComposer(), Thread(false),
85edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mTransactionFlags(0),
8628378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        mTransationPending(false),
87076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved(false),
8852bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        mRepaintEverything(0),
89edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mBootTime(systemTime()),
90edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mVisibleRegionsDirty(false),
91a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        mHwWorkListDirty(false),
92edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDebugRegion(0),
938afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian        mDebugDDMS(0),
9473d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian        mDebugDisableHWC(0),
95a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian        mDebugDisableTransformHint(0),
969795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInSwapBuffers(0),
979795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastSwapBufferTime(0),
989795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInTransaction(0),
999795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastTransactionTime(0),
1005f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        mBootFinished(false)
101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
102a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI("SurfaceFlinger is starting");
103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // debugging stuff...
105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char value[PROPERTY_VALUE_MAX];
1068afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    property_get("debug.sf.showupdates", value, "0");
108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDebugRegion = atoi(value);
1098afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
1108afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    property_get("debug.sf.ddms", value, "0");
1118afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    mDebugDDMS = atoi(value);
1128afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    if (mDebugDDMS) {
11363f165fd6b86d04be94d4023e845e98560504a96Keun young Park        if (!startDdmConnection()) {
11463f165fd6b86d04be94d4023e845e98560504a96Keun young Park            // start failed, and DDMS debugging not enabled
11563f165fd6b86d04be94d4023e845e98560504a96Keun young Park            mDebugDDMS = 0;
11663f165fd6b86d04be94d4023e845e98560504a96Keun young Park        }
1178afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    }
118c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    ALOGI_IF(mDebugRegion, "showupdates enabled");
119c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    ALOGI_IF(mDebugDDMS, "DDMS debugging enabled");
120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
12299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::onFirstRef()
12399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
12499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.init(this);
12599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
12699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY);
12799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
12899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // Wait for the main thread to be done with its initialization
12999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mReadyToRunBarrier.wait();
13099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
13199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
13299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::~SurfaceFlinger()
134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
135a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
136a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
137a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglTerminate(display);
138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
14099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::binderDied(const wp<IBinder>& who)
14199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
14299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // the window manager died on us. prepare its eulogy.
14399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
14413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    // restore initial conditions (default device unblank, etc)
14513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    initializeDisplays();
14699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
14799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // restart the boot-animation
148a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    startBootAnim();
14999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
15099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
1517e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopiansp<ISurfaceComposerClient> SurfaceFlinger::createConnection()
152edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
15396f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<ISurfaceComposerClient> bclient;
15496f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<Client> client(new Client(this));
15596f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = client->initCheck();
15696f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR) {
15796f0819f81293076e652792794a961543e6750d7Mathias Agopian        bclient = client;
158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return bclient;
160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
162e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopiansp<IBinder> SurfaceFlinger::createDisplay()
163e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{
164e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    class DisplayToken : public BBinder {
165e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        sp<SurfaceFlinger> flinger;
166e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        virtual ~DisplayToken() {
167e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             // no more references, this display must be terminated
168e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             Mutex::Autolock _l(flinger->mStateLock);
169e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             flinger->mCurrentState.displays.removeItem(this);
170e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             flinger->setTransactionFlags(eDisplayTransactionNeeded);
171e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian         }
172e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian     public:
173e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        DisplayToken(const sp<SurfaceFlinger>& flinger)
174e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            : flinger(flinger) {
175e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
176e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    };
177e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
178e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    sp<BBinder> token = new DisplayToken(this);
179e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
180e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    Mutex::Autolock _l(mStateLock);
1813ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    DisplayDeviceState info(DisplayDevice::DISPLAY_VIRTUAL);
182e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    mCurrentState.displays.add(token, info);
183e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
184e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return token;
185e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
186e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
187e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopiansp<IBinder> SurfaceFlinger::getBuiltInDisplay(int32_t id) {
1883ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    if (uint32_t(id) >= DisplayDevice::NUM_DISPLAY_TYPES) {
189e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        ALOGE("getDefaultDisplay: id=%d is not a valid default display id", id);
190e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        return NULL;
191e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
192e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return mDefaultDisplays[id];
193e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
194e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
1959a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc()
1969a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis{
1979a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc());
1989a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    return gba;
1999a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis}
200b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
201edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::bootFinished()
202edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
203edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t now = systemTime();
204edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t duration = now - mBootTime;
205a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
2063330b203039dea366d4981db1408a460134b2d2cMathias Agopian    mBootFinished = true;
2071f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
2081f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // wait patiently for the window manager death
2091f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    const String16 name("window");
2101f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    sp<IBinder> window(defaultServiceManager()->getService(name));
2111f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    if (window != 0) {
212921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        window->linkToDeath(static_cast<IBinder::DeathRecipient*>(this));
2131f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    }
2141f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
2151f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // stop boot animation
216a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // formerly we would just kill the process, but we now ask it to exit so it
217a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // can choose where to stop the animation.
218a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("service.bootanim.exit", "1");
219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
221921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianvoid SurfaceFlinger::deleteTextureAsync(GLuint texture) {
222921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    class MessageDestroyGLTexture : public MessageBase {
223921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        GLuint texture;
224921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    public:
225921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        MessageDestroyGLTexture(GLuint texture)
226921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian            : texture(texture) {
227921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        }
228921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        virtual bool handler() {
229921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian            glDeleteTextures(1, &texture);
230921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian            return true;
231921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        }
232921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    };
233921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    postMessageAsync(new MessageDestroyGLTexture(texture));
234921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
235921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
236a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianstatus_t SurfaceFlinger::selectConfigForPixelFormat(
237a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        EGLDisplay dpy,
238a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        EGLint const* attrs,
239a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        PixelFormat format,
240a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        EGLConfig* outConfig)
241a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian{
242a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLConfig config = NULL;
243a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLint numConfigs = -1, n=0;
244a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglGetConfigs(dpy, NULL, 0, &numConfigs);
245a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLConfig* const configs = new EGLConfig[numConfigs];
246a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglChooseConfig(dpy, attrs, configs, numConfigs, &n);
247cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian
248a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    for (int i=0 ; i<n ; i++) {
249a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        EGLint nativeVisualId = 0;
250a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        eglGetConfigAttrib(dpy, configs[i], EGL_NATIVE_VISUAL_ID, &nativeVisualId);
251a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        if (nativeVisualId>0 && format == nativeVisualId) {
252a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            *outConfig = configs[i];
253a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            delete [] configs;
254a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            return NO_ERROR;
255a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        }
256a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    }
257a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    delete [] configs;
258a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    return NAME_NOT_FOUND;
259edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
261a49126087b4494f4ef50873f3a3f6727265f6621Mathias AgopianEGLConfig SurfaceFlinger::selectEGLConfig(EGLDisplay display, EGLint nativeVisualId) {
262a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // select our EGLConfig. It must support EGL_RECORDABLE_ANDROID if
263a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // it is to be used with WIFI displays
264a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLConfig config;
265a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLint dummy;
266a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    status_t err;
267da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
268a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLint attribs[] = {
269a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            EGL_SURFACE_TYPE,           EGL_WINDOW_BIT,
270cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian            EGL_RED_SIZE,               8,
271cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian            EGL_GREEN_SIZE,             8,
272cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian            EGL_BLUE_SIZE,              8,
273cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian            // EGL_RECORDABLE_ANDROID must be last so that we can retry
274cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian            // without it easily (see below)
275a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            EGL_RECORDABLE_ANDROID,     EGL_TRUE,
276a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            EGL_NONE
277a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    };
278a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    err = selectConfigForPixelFormat(display, attribs, nativeVisualId, &config);
279a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    if (err) {
280a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        // maybe we failed because of EGL_RECORDABLE_ANDROID
281a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        ALOGW("couldn't find an EGLConfig with EGL_RECORDABLE_ANDROID");
282cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian        attribs[NELEM(attribs) - 3] = EGL_NONE;
283a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        err = selectConfigForPixelFormat(display, attribs, nativeVisualId, &config);
284a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    }
285a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGE_IF(err, "couldn't find an EGLConfig matching the screen format");
286a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    if (eglGetConfigAttrib(display, config, EGL_CONFIG_CAVEAT, &dummy) == EGL_TRUE) {
287a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        ALOGW_IF(dummy == EGL_SLOW_CONFIG, "EGL_SLOW_CONFIG selected!");
288a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    }
289a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    return config;
290a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
291edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
292a49126087b4494f4ef50873f3a3f6727265f6621Mathias AgopianEGLContext SurfaceFlinger::createGLContext(EGLDisplay display, EGLConfig config) {
293a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // Also create our EGLContext
294a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLint contextAttributes[] = {
295a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#ifdef EGL_IMG_context_priority
296a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#ifdef HAS_CONTEXT_PRIORITY
297a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#warning "using EGL_IMG_context_priority"
298a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_HIGH_IMG,
299a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#endif
300a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#endif
301a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            EGL_NONE, EGL_NONE
302a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    };
303a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLContext ctxt = eglCreateContext(display, config, NULL, contextAttributes);
304a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGE_IF(ctxt==EGL_NO_CONTEXT, "EGLContext creation failed");
305a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    return ctxt;
306a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
308cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopianvoid SurfaceFlinger::initializeGL(EGLDisplay display) {
309a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    GLExtensions& extensions(GLExtensions::getInstance());
310a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    extensions.initWithGLStrings(
311a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            glGetString(GL_VENDOR),
312a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            glGetString(GL_RENDERER),
313a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            glGetString(GL_VERSION),
314a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            glGetString(GL_EXTENSIONS),
315a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            eglQueryString(display, EGL_VENDOR),
316a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            eglQueryString(display, EGL_VERSION),
317a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            eglQueryString(display, EGL_EXTENSIONS));
3188b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
319a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
320a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    glGetIntegerv(GL_MAX_VIEWPORT_DIMS, mMaxViewportDims);
3217303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
3238b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber    glPixelStorei(GL_PACK_ALIGNMENT, 4);
324edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glEnableClientState(GL_VERTEX_ARRAY);
325edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glShadeModel(GL_FLAT);
326edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_DITHER);
327edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_CULL_FACE);
328edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
329a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    struct pack565 {
330a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        inline uint16_t operator() (int r, int g, int b) const {
331a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            return (r<<11)|(g<<5)|b;
332a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        }
333a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    } pack565;
334a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
3359575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    const uint16_t protTexData[] = { pack565(0x03, 0x03, 0x03) };
3369575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glGenTextures(1, &mProtectedTexName);
3379575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glBindTexture(GL_TEXTURE_2D, mProtectedTexName);
3389575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3399575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3409575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
3419575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
3429575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0,
3439575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis            GL_RGB, GL_UNSIGNED_SHORT_5_6_5, protTexData);
344edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
345a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // print some debugging info
346a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLint r,g,b,a;
347a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglGetConfigAttrib(display, mEGLConfig, EGL_RED_SIZE,   &r);
348a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglGetConfigAttrib(display, mEGLConfig, EGL_GREEN_SIZE, &g);
349a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglGetConfigAttrib(display, mEGLConfig, EGL_BLUE_SIZE,  &b);
350a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglGetConfigAttrib(display, mEGLConfig, EGL_ALPHA_SIZE, &a);
351a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("EGL informations:");
352a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("vendor    : %s", extensions.getEglVendor());
353a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("version   : %s", extensions.getEglVersion());
354a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("extensions: %s", extensions.getEglExtension());
355a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("Client API: %s", eglQueryString(display, EGL_CLIENT_APIS)?:"Not Supported");
356a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("EGLSurface: %d-%d-%d-%d, config=%p", r, g, b, a, mEGLConfig);
357a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("OpenGL ES informations:");
358a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("vendor    : %s", extensions.getVendor());
359a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("renderer  : %s", extensions.getRenderer());
360a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("version   : %s", extensions.getVersion());
361a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("extensions: %s", extensions.getExtension());
362a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("GL_MAX_TEXTURE_SIZE = %d", mMaxTextureSize);
363a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("GL_MAX_VIEWPORT_DIMS = %d x %d", mMaxViewportDims[0], mMaxViewportDims[1]);
364a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
365a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
366a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianstatus_t SurfaceFlinger::readyToRun()
367a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian{
368a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI(  "SurfaceFlinger's main thread ready to run. "
369a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            "Initializing graphics H/W...");
370a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
371b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden    // initialize EGL for the default display
37234a09ba1efd706323a15633da5044b352988eb5fJesse Hall    mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
37334a09ba1efd706323a15633da5044b352988eb5fJesse Hall    eglInitialize(mEGLDisplay, NULL, NULL);
374a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
375b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden    // Initialize the H/W composer object.  There may or may not be an
376b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden    // actual hardware composer underneath.
377b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden    mHwc = new HWComposer(this,
378b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden            *static_cast<HWComposer::EventHandler *>(this));
379b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden
380a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // initialize the config and context
381cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian    EGLint format = mHwc->getVisualID();
38234a09ba1efd706323a15633da5044b352988eb5fJesse Hall    mEGLConfig  = selectEGLConfig(mEGLDisplay, format);
38334a09ba1efd706323a15633da5044b352988eb5fJesse Hall    mEGLContext = createGLContext(mEGLDisplay, mEGLConfig);
384a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
385da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian    LOG_ALWAYS_FATAL_IF(mEGLContext == EGL_NO_CONTEXT,
386da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian            "couldn't create EGLContext");
387da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
388cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian    // initialize our non-virtual displays
3893ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    for (size_t i=0 ; i<DisplayDevice::NUM_DISPLAY_TYPES ; i++) {
390e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        mDefaultDisplays[i] = new BBinder();
3913ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian        mCurrentState.displays.add(mDefaultDisplays[i],
392cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                DisplayDeviceState(DisplayDevice::DisplayType(i)));
393e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
394cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian
395cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian    // The main display is a bit special and always exists
396cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian    //
397cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian    // if we didn't add it here, it would be added automatically during the
398cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian    // first transaction, however this would also create some difficulties:
399cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian    //
400cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian    // - there would be a race where a client could call getDisplayInfo(),
401cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian    //   for instance before the DisplayDevice is created.
402cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian    //
403cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian    // - we need a GL context current in a few places, when initializing
404cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian    //   OpenGL ES (see below), or creating a layer,
405cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian    //   or when a texture is (asynchronously) destroyed, and for that
406cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian    //   we need a valid surface, so it's conveniant to use the main display
407cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian    //   for that.
408cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian
409cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian    sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc);
410cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian    sp<SurfaceTextureClient> stc = new SurfaceTextureClient(
411cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                static_cast< sp<ISurfaceTexture> >(fbs->getBufferQueue()));
412e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    sp<DisplayDevice> hw = new DisplayDevice(this,
4133ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian            DisplayDevice::DISPLAY_PRIMARY,
4143ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian            mDefaultDisplays[DisplayDevice::DISPLAY_PRIMARY],
415cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian            stc, fbs, mEGLConfig);
4163ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    mDisplays.add(mDefaultDisplays[DisplayDevice::DISPLAY_PRIMARY], hw);
417a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
418cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian
419a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    //  initialize OpenGL ES
420cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian    DisplayDevice::makeCurrent(mEGLDisplay, hw, mEGLContext);
421cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian    initializeGL(mEGLDisplay);
422d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
423028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian    // start the EventThread
424028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian    mEventThread = new EventThread(this);
425028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian    mEventQueue.setEventThread(mEventThread);
426028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian
42792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    // initialize our drawing state
42892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    mDrawingState = mCurrentState;
4298630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
430cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian
431a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // We're now ready to accept clients...
432d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian    mReadyToRunBarrier.open();
433d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
43413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    // set initial conditions (e.g. unblank default device)
43513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    initializeDisplays();
43613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
437a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    // start boot animation
438a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    startBootAnim();
4398b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
440edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
441edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
442edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
4433ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopianint32_t SurfaceFlinger::allocateHwcDisplayId(DisplayDevice::DisplayType type) {
4443ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    return (uint32_t(type) < DisplayDevice::NUM_DISPLAY_TYPES) ?
4453ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian            type : mHwc->allocateDisplayId();
4463ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian}
4473ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian
448a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopianvoid SurfaceFlinger::startBootAnim() {
449a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // start boot animation
450a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("service.bootanim.exit", "0");
451a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("ctl.start", "bootanim");
452a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian}
453a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian
454a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianuint32_t SurfaceFlinger::getMaxTextureSize() const {
455a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    return mMaxTextureSize;
456a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
457a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
458a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianuint32_t SurfaceFlinger::getMaxViewportDims() const {
459a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    return mMaxViewportDims[0] < mMaxViewportDims[1] ?
460a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            mMaxViewportDims[0] : mMaxViewportDims[1];
461a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
462a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
463edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
464d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
465582270d69db94286a248bd829f1ae6f910d45124Jamie Gennisbool SurfaceFlinger::authenticateSurfaceTexture(
466582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis        const sp<ISurfaceTexture>& surfaceTexture) const {
467134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    Mutex::Autolock _l(mStateLock);
468582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis    sp<IBinder> surfaceTextureBinder(surfaceTexture->asBinder());
469134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
470134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // Check the visible layer list for the ISurface
471134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
472134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    size_t count = currentLayers.size();
473134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    for (size_t i=0 ; i<count ; i++) {
474134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        const sp<LayerBase>& layer(currentLayers[i]);
475134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        sp<LayerBaseClient> lbc(layer->getLayerBaseClient());
476582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis        if (lbc != NULL) {
477582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder();
478582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            if (lbcBinder == surfaceTextureBinder) {
479582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis                return true;
480582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            }
481134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        }
482134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    }
483134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
484134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // Check the layers in the purgatory.  This check is here so that if a
485582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis    // SurfaceTexture gets destroyed before all the clients are done using it,
486582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis    // the error will not be reported as "surface XYZ is not authenticated", but
487134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // will instead fail later on when the client tries to use the surface,
488134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // which should be reported as "surface XYZ returned an -ENODEV".  The
489134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // purgatorized layers are no less authentic than the visible ones, so this
490134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // should not cause any harm.
491134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    size_t purgatorySize =  mLayerPurgatory.size();
492134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    for (size_t i=0 ; i<purgatorySize ; i++) {
493134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
494134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        sp<LayerBaseClient> lbc(layer->getLayerBaseClient());
495582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis        if (lbc != NULL) {
496582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder();
497582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            if (lbcBinder == surfaceTextureBinder) {
498582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis                return true;
499582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            }
500134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        }
501134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    }
502134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
503134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    return false;
504134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis}
505134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
5069d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brownstatus_t SurfaceFlinger::getDisplayInfo(const sp<IBinder>& display, DisplayInfo* info) {
5079d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown    // TODO: this is mostly here only for compatibility
5089d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown    //       the display size is needed but the display metrics should come from elsewhere
5099d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown    if (display != mDefaultDisplays[ISurfaceComposer::eDisplayIdMain]) {
5109d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown        // TODO: additional displays not yet supported
511c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian        return BAD_INDEX;
512c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian    }
5138b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian
5148b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    const HWComposer& hwc(getHwComposer());
515b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden    float xdpi = hwc.getDpiX(HWC_DISPLAY_PRIMARY);
516b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden    float ydpi = hwc.getDpiY(HWC_DISPLAY_PRIMARY);
5178b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian
5188b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    // TODO: Not sure if display density should handled by SF any longer
5198b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    class Density {
5208b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        static int getDensityFromProperty(char const* propName) {
5218b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            char property[PROPERTY_VALUE_MAX];
5228b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            int density = 0;
5238b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            if (property_get(propName, property, NULL) > 0) {
5248b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian                density = atoi(property);
5258b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            }
5268b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            return density;
5278b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        }
5288b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    public:
5298b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        static int getEmuDensity() {
5308b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            return getDensityFromProperty("qemu.sf.lcd_density"); }
5318b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        static int getBuildDensity()  {
5328b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            return getDensityFromProperty("ro.sf.lcd_density"); }
5338b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    };
5348b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    // The density of the device is provided by a build property
5358b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    float density = Density::getBuildDensity() / 160.0f;
5368b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    if (density == 0) {
5378b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        // the build doesn't provide a density -- this is wrong!
5388b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        // use xdpi instead
5398b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        ALOGE("ro.sf.lcd_density must be defined as a build property");
5408b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        density = xdpi / 160.0f;
5418b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    }
5428b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    if (Density::getEmuDensity()) {
5438b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        // if "qemu.sf.lcd_density" is specified, it overrides everything
5448b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        xdpi = ydpi = density = Density::getEmuDensity();
5458b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        density /= 160.0f;
5468b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    }
5478b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian
5484297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    sp<const DisplayDevice> hw(getDefaultDisplayDevice());
5494297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    info->w = hw->getWidth();
5504297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    info->h = hw->getHeight();
5518b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    info->xdpi = xdpi;
5528b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    info->ydpi = ydpi;
553b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden    info->fps = float(1e9 / hwc.getRefreshPeriod(HWC_DISPLAY_PRIMARY));
5548b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    info->density = density;
5554297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    info->orientation = hw->getOrientation();
556888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian    // TODO: this needs to go away (currently needed only by webkit)
5574297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    getPixelFormatInfo(hw->getFormat(), &info->pixelFormatInfo);
558888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian    return NO_ERROR;
559c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian}
560c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian
561d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian// ----------------------------------------------------------------------------
562d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
563d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopiansp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection() {
5648aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian    return mEventThread->createEventConnection();
565bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian}
566bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
5679d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brownvoid SurfaceFlinger::connectDisplay(const sp<ISurfaceTexture>& surface) {
5683094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
5695f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    sp<IBinder> token;
5703094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    { // scope for the lock
5713094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        Mutex::Autolock _l(mStateLock);
5725f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        token = mExtDisplayToken;
5733094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    }
5743094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
5755f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    if (token == 0) {
5765f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        token = createDisplay();
5773094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    }
5783094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
5795f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    { // scope for the lock
5805f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        Mutex::Autolock _l(mStateLock);
5815f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        if (surface == 0) {
5825f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian            // release our current display. we're guarantee to have
5835f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian            // a reference to it (token), while we hold the lock
5845f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian            mExtDisplayToken = 0;
5855f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        } else {
5865f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian            mExtDisplayToken = token;
5875f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        }
5885f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian
5895f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        DisplayDeviceState& info(mCurrentState.displays.editValueFor(token));
5905f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        info.surface = surface;
5915f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        setTransactionFlags(eDisplayTransactionNeeded);
5925f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    }
5933094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian}
5943094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
595edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
59699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
59799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::waitForEvent() {
59899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.waitMessage();
59999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
60099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
60199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalTransaction() {
60299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.invalidate();
60399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
60499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
60599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalLayerUpdate() {
60699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.invalidate();
60799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
60899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
60999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalRefresh() {
61099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.refresh();
61199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
61299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
61399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg,
61499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        nsecs_t reltime, uint32_t flags) {
61599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return mEventQueue.postMessage(msg, reltime);
61699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
61799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
61899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,
61999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        nsecs_t reltime, uint32_t flags) {
62099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    status_t res = mEventQueue.postMessage(msg, reltime);
62199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    if (res == NO_ERROR) {
62299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        msg->wait();
62399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    }
62499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return res;
62599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
626edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
6274fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianbool SurfaceFlinger::threadLoop() {
628edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    waitForEvent();
62999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return true;
63099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
631edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
6323ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopianvoid SurfaceFlinger::onVSyncReceived(int type, nsecs_t timestamp) {
63343601a2dc320a271ff8c3765ff61414a07221635Andy McFadden    if (mEventThread == NULL) {
63443601a2dc320a271ff8c3765ff61414a07221635Andy McFadden        // This is a temporary workaround for b/7145521.  A non-null pointer
63543601a2dc320a271ff8c3765ff61414a07221635Andy McFadden        // does not mean EventThread has finished initializing, so this
63643601a2dc320a271ff8c3765ff61414a07221635Andy McFadden        // is not a correct fix.
63743601a2dc320a271ff8c3765ff61414a07221635Andy McFadden        ALOGW("WARNING: EventThread not started, ignoring vsync");
63843601a2dc320a271ff8c3765ff61414a07221635Andy McFadden        return;
63943601a2dc320a271ff8c3765ff61414a07221635Andy McFadden    }
6403ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    if (uint32_t(type) < DisplayDevice::NUM_DISPLAY_TYPES) {
6413ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian        // we should only receive DisplayDevice::DisplayType from the vsync callback
6423ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian        const wp<IBinder>& token(mDefaultDisplays[type]);
6433ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian        mEventThread->onVSyncReceived(token, timestamp);
6443ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    }
6458630320433bd15aca239522e54e711ef6372ab07Mathias Agopian}
6468630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
6478630320433bd15aca239522e54e711ef6372ab07Mathias Agopianvoid SurfaceFlinger::eventControl(int event, int enabled) {
6488630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    getHwComposer().eventControl(event, enabled);
6498630320433bd15aca239522e54e711ef6372ab07Mathias Agopian}
6508630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
6514fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::onMessageReceived(int32_t what) {
6521c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
65399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    switch (what) {
6544fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    case MessageQueue::INVALIDATE:
6554fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        handleMessageTransaction();
6564fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        handleMessageInvalidate();
6574fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        signalRefresh();
6584fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        break;
6594fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    case MessageQueue::REFRESH:
6604fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        handleMessageRefresh();
6614fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        break;
6624fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
6634fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
664edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
6654fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageTransaction() {
666e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    uint32_t transactionFlags = peekTransactionFlags(eTransactionMask);
6674fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    if (transactionFlags) {
66887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        handleTransaction(transactionFlags);
6694fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
6704fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
671edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
6724fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageInvalidate() {
673cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    ATRACE_CALL();
67487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    handlePageFlip();
6754fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
6763a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian
6774fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageRefresh() {
678cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    ATRACE_CALL();
679cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    preComposition();
680cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    rebuildLayerStacks();
681cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    setUpHWComposer();
682cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    doDebugFlashRegions();
683cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    doComposition();
684cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    postComposition();
685cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
686cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
687cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doDebugFlashRegions()
688cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{
689cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    // is debugging enabled
690cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (CC_LIKELY(!mDebugRegion))
691cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        return;
692cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
693cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    const bool repaintEverything = mRepaintEverything;
694cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
695cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
696cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        if (hw->canDraw()) {
697cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            // transform the dirty region into this screen's coordinate space
698cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            const Region dirtyRegion(hw->getDirtyRegion(repaintEverything));
699cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            if (!dirtyRegion.isEmpty()) {
700cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                // redraw the whole screen
701cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                doComposeSurfaces(hw, Region(hw->bounds()));
702cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
703cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                // and draw the dirty region
704cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                glDisable(GL_TEXTURE_EXTERNAL_OES);
705cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                glDisable(GL_TEXTURE_2D);
706cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                glDisable(GL_BLEND);
707cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                glColor4f(1, 0, 1, 1);
708cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                const int32_t height = hw->getHeight();
709cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                Region::const_iterator it = dirtyRegion.begin();
710cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                Region::const_iterator const end = dirtyRegion.end();
711cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                while (it != end) {
712cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                    const Rect& r = *it++;
713cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                    GLfloat vertices[][2] = {
714cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            { r.left,  height - r.top },
715cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            { r.left,  height - r.bottom },
716cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            { r.right, height - r.bottom },
717cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            { r.right, height - r.top }
718cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                    };
719cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                    glVertexPointer(2, GL_FLOAT, 0, vertices);
720cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
721cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                }
722cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                hw->compositionComplete();
723da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                hw->swapBuffers(getHwComposer());
724cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            }
725cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        }
726cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
727cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
728cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    postFramebuffer();
729cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
730cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (mDebugRegion > 1) {
731cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        usleep(mDebugRegion * 1000);
732cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
733cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
734cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
735cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::preComposition()
736cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{
737cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    bool needExtraInvalidate = false;
738cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
739cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    const size_t count = currentLayers.size();
740cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    for (size_t i=0 ; i<count ; i++) {
741cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        if (currentLayers[i]->onPreComposition()) {
742cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            needExtraInvalidate = true;
743cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        }
744cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
745cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (needExtraInvalidate) {
746cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        signalLayerUpdate();
747cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
748cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
749a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
750cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::postComposition()
751cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{
752cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
753cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    const size_t count = currentLayers.size();
754cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    for (size_t i=0 ; i<count ; i++) {
755cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        currentLayers[i]->onPostComposition();
756cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
757cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
758cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
759cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::rebuildLayerStacks() {
760cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    // rebuild the visible layer list per screen
76152bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    if (CC_UNLIKELY(mVisibleRegionsDirty)) {
762cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        ATRACE_CALL();
76387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        mVisibleRegionsDirty = false;
76487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        invalidateHwcGeometry();
765ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian
76687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
76792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
768ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian            Region opaqueRegion;
769ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian            Region dirtyRegion;
770ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian            Vector< sp<LayerBase> > layersSortedByZ;
7714297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            const sp<DisplayDevice>& hw(mDisplays[dpy]);
7727e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian            const Transform& tr(hw->getTransform());
7737e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian            const Rect bounds(hw->getBounds());
774ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian            if (hw->canDraw()) {
775ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                SurfaceFlinger::computeVisibleRegions(currentLayers,
776ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                        hw->getLayerStack(), dirtyRegion, opaqueRegion);
7777e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian
778ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                const size_t count = currentLayers.size();
779ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                for (size_t i=0 ; i<count ; i++) {
780ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                    const sp<LayerBase>& layer(currentLayers[i]);
781ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                    const Layer::State& s(layer->drawingState());
782ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                    if (s.layerStack == hw->getLayerStack()) {
783ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                        Region visibleRegion(tr.transform(layer->visibleRegion));
784ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                        visibleRegion.andSelf(bounds);
785ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                        if (!visibleRegion.isEmpty()) {
786ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                            layersSortedByZ.add(layer);
787ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                        }
78887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian                    }
78987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian                }
7903b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian            }
7914297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->setVisibleLayersSortedByZ(layersSortedByZ);
7927e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian            hw->undefinedRegion.set(bounds);
7937e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian            hw->undefinedRegion.subtractSelf(tr.transform(opaqueRegion));
7947e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian            hw->dirtyRegion.orSelf(dirtyRegion);
7953b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        }
7963b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
797cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
7983b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
799cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::setUpHWComposer() {
80052bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    HWComposer& hwc(getHwComposer());
80152bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    if (hwc.initCheck() == NO_ERROR) {
80252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        // build the h/w work list
80352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        const bool workListsDirty = mHwWorkListDirty;
80452bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        mHwWorkListDirty = false;
80592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
8064297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            sp<const DisplayDevice> hw(mDisplays[dpy]);
807e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian            const int32_t id = hw->getHwcDisplayId();
808e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian            if (id >= 0) {
809e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                const Vector< sp<LayerBase> >& currentLayers(
810cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                    hw->getVisibleLayersSortedByZ());
811e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                const size_t count = currentLayers.size();
812e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                if (hwc.createWorkList(id, count) >= 0) {
813e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                    HWComposer::LayerListIterator cur = hwc.begin(id);
814e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                    const HWComposer::LayerListIterator end = hwc.end(id);
815e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                    for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
816e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                        const sp<LayerBase>& layer(currentLayers[i]);
817e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian
818e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                        if (CC_UNLIKELY(workListsDirty)) {
819e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                            layer->setGeometry(hw, *cur);
820e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                            if (mDebugDisableHWC || mDebugRegion) {
821e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                                cur->setSkip(true);
822e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                            }
8231e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                        }
82452bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian
825e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                        /*
826e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                         * update the per-frame h/w composer data for each layer
827e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                         * and build the transparent region of the FB
828e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                         */
829e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                        layer->setPerFrameData(hw, *cur);
830e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                    }
8311e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                }
83252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            }
83387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        }
83452bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        status_t err = hwc.prepare();
83552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
83652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    }
837cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
83852bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian
839cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doComposition() {
840cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    ATRACE_CALL();
84152bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    const bool repaintEverything = android_atomic_and(0, &mRepaintEverything);
84292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
8434297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
844cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        if (hw->canDraw()) {
845cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            // transform the dirty region into this screen's coordinate space
846cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            const Region dirtyRegion(hw->getDirtyRegion(repaintEverything));
847cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            if (!dirtyRegion.isEmpty()) {
84852bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian                // repaint the framebuffer (if needed)
849cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                doDisplayComposition(hw, dirtyRegion);
85052bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            }
851cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            hw->dirtyRegion.clear();
852cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            hw->flip(hw->swapRegion);
853cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            hw->swapRegion.clear();
85487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        }
85552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        // inform the h/w that we're done compositing
8564297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        hw->compositionComplete();
8574fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
85852bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    postFramebuffer();
859edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
860edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
861edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer()
862edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
863841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
864b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian
865a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    const nsecs_t now = systemTime();
866a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = now;
867c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall
86852bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    HWComposer& hwc(getHwComposer());
869ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall    if (hwc.initCheck() == NO_ERROR) {
8705f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        // FIXME: EGL spec says:
8715f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        //   "surface must be bound to the calling thread's current context,
8725f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        //    for the current rendering API."
873da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian        DisplayDevice::makeCurrent(mEGLDisplay, getDefaultDisplayDevice(), mEGLContext);
874e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian        hwc.commit();
87552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    }
87652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian
87792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
8784297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        sp<const DisplayDevice> hw(mDisplays[dpy]);
8794297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const Vector< sp<LayerBase> >& currentLayers(hw->getVisibleLayersSortedByZ());
880da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian        hw->onSwapBuffersCompleted(hwc);
88152bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        const size_t count = currentLayers.size();
882e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian        int32_t id = hw->getHwcDisplayId();
883e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian        if (id >=0 && hwc.initCheck() == NO_ERROR) {
8841e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian            HWComposer::LayerListIterator cur = hwc.begin(id);
8851e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian            const HWComposer::LayerListIterator end = hwc.end(id);
88652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            for (size_t i = 0; cur != end && i < count; ++i, ++cur) {
887d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian                currentLayers[i]->onLayerDisplayed(hw, &*cur);
88852bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            }
889cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        } else {
89052bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            for (size_t i = 0; i < count; i++) {
891d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian                currentLayers[i]->onLayerDisplayed(hw, NULL);
89252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            }
893ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall        }
894e8696a40e09b24b634214684d18526187b316a2fJamie Gennis    }
895e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
896a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mLastSwapBufferTime = systemTime() - now;
897a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = 0;
898edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
899edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
90087baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
901edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
902841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
903841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
904ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    Mutex::Autolock _l(mStateLock);
905ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    const nsecs_t now = systemTime();
906ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = now;
907ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
908ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // Here we're guaranteed that some transaction flags are set
909ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // so we can call handleTransactionLocked() unconditionally.
910ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // We call getTransactionFlags(), which will also clear the flags,
911ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // with mStateLock held to guarantee that mCurrentState won't change
912ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // until the transaction is committed.
913ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
914e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    transactionFlags = getTransactionFlags(eTransactionMask);
91587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    handleTransactionLocked(transactionFlags);
916ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
917ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mLastTransactionTime = systemTime() - now;
918ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = 0;
919ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    invalidateHwcGeometry();
920ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // here the transaction has been committed
9213d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian}
922edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
92387baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
9243d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{
9253d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    const LayerVector& currentLayers(mCurrentState.layersSortedByZ);
926edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t count = currentLayers.size();
927edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
928edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
929edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Traversal of the children
930edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * (perform the transaction for each of them if needed)
931edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
932edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
9333559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    if (transactionFlags & eTraversalNeeded) {
934edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (size_t i=0 ; i<count ; i++) {
935076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            const sp<LayerBase>& layer = currentLayers[i];
936edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
937edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (!trFlags) continue;
938edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
939edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const uint32_t flags = layer->doTransaction(0);
940edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (flags & Layer::eVisibleRegion)
941edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mVisibleRegionsDirty = true;
942edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
943edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
944edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
945edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
9463559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian     * Perform display own transactions if needed
947edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
948edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
949e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    if (transactionFlags & eDisplayTransactionNeeded) {
95092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        // here we take advantage of Vector's copy-on-write semantics to
95192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        // improve performance by skipping the transaction entirely when
95292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        // know that the lists are identical
953e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const KeyedVector<  wp<IBinder>, DisplayDeviceState>& curr(mCurrentState.displays);
954e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const KeyedVector<  wp<IBinder>, DisplayDeviceState>& draw(mDrawingState.displays);
95592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        if (!curr.isIdenticalTo(draw)) {
956edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
95792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            const size_t cc = curr.size();
95893997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                  size_t dc = draw.size();
95992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian
96092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // find the displays that were removed
96192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // (ie: in drawing state but not in current state)
96292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // also handle displays that changed
96392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // (ie: displays that are in both lists)
96492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            for (size_t i=0 ; i<dc ; i++) {
965e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                const ssize_t j = curr.indexOfKey(draw.keyAt(i));
966e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                if (j < 0) {
96792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    // in drawing state but not in current state
9683ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian                    if (!draw[i].isMainDisplay()) {
9693ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian                        mDisplays.removeItem(draw.keyAt(i));
97092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    } else {
97192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                        ALOGW("trying to remove the main display");
97292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    }
97392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                } else {
97492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    // this display is in both lists. see if something changed.
975e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                    const DisplayDeviceState& state(curr[j]);
9763ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian                    const wp<IBinder>& display(curr.keyAt(j));
977111b2d89221722d38f5b5b3ba65904ec22421839Mathias Agopian                    if (state.surface->asBinder() != draw[i].surface->asBinder()) {
978e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        // changing the surface is like destroying and
97993997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // recreating the DisplayDevice, so we just remove it
98093997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // from the drawing state, so that it get re-added
98193997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // below.
98293997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        mDisplays.removeItem(display);
98393997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        mDrawingState.displays.removeItemsAt(i);
98493997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        dc--; i--;
98593997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // at this point we must loop to the next item
98693997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        continue;
98792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    }
98893997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian
98993997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                    const sp<DisplayDevice>& disp(getDisplayDevice(display));
99093997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                    if (disp != NULL) {
99193997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        if (state.layerStack != draw[i].layerStack) {
99293997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                            disp->setLayerStack(state.layerStack);
99393997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        }
99400e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                        if ((state.orientation != draw[i].orientation)
99500e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                                || (state.viewport != draw[i].viewport)
99600e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                                || (state.frame != draw[i].frame))
99700e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                        {
99800e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                            disp->setProjection(state.orientation,
9994fb3999cea652617be5125f8a42c257467bf3c77Jeff Brown                                    state.viewport, state.frame);
100093997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        }
10016905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden
10026905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                        // Walk through all the layers in currentLayers,
10036905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                        // and update their transform hint.
10046905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                        //
10056905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                        // TODO: we could be much more clever about which
10066905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                        // layers we touch and how often we do these updates
10076905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                        // (e.g. only touch the layers associated with this
10086905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                        // display, and only on a rotation).
10096905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                        for (size_t i = 0; i < count; i++) {
10106905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                            const sp<LayerBase>& layerBase = currentLayers[i];
10116905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                            layerBase->updateTransformHint();
10126905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                        }
101392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    }
101492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                }
101592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            }
101692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian
101792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // find displays that were added
101892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // (ie: in current state but not in drawing state)
101992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            for (size_t i=0 ; i<cc ; i++) {
1020e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                if (draw.indexOfKey(curr.keyAt(i)) < 0) {
1021e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                    const DisplayDeviceState& state(curr[i]);
1022cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian
1023cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                    sp<FramebufferSurface> fbs;
1024cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                    sp<SurfaceTextureClient> stc;
1025cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                    if (!state.isVirtualDisplay()) {
1026cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian
1027cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        ALOGE_IF(state.surface!=NULL,
1028cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                                "adding a supported display, but rendering "
1029cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                                "surface is provided (%p), ignoring it",
1030cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                                state.surface.get());
1031cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian
1032cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        // for supported (by hwc) displays we provide our
1033cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        // own rendering surface
1034cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        fbs = new FramebufferSurface(*mHwc);
1035cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        stc = new SurfaceTextureClient(
1036cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                                static_cast< sp<ISurfaceTexture> >(fbs->getBufferQueue()));
1037cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                    } else {
1038cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        if (state.surface != NULL) {
1039cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                            stc = new SurfaceTextureClient(state.surface);
1040cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        }
1041cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                    }
1042cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian
1043cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                    const wp<IBinder>& display(curr.keyAt(i));
1044cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                    if (stc != NULL) {
1045cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        sp<DisplayDevice> hw = new DisplayDevice(this,
1046cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                                state.type, display, stc, fbs, mEGLConfig);
1047cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        hw->setLayerStack(state.layerStack);
1048cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        hw->setProjection(state.orientation,
10494fb3999cea652617be5125f8a42c257467bf3c77Jeff Brown                                state.viewport, state.frame);
1050cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        mDisplays.add(display, hw);
1051cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        if (hw->getDisplayType() < DisplayDevice::NUM_DISPLAY_TYPES) {
1052cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                            // notify the system that this display is now up
1053cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                            // (note onScreenAcquired() is safe to call from
1054cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                            // here because we're in the main thread)
1055cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                            onScreenAcquired(hw);
1056cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        }
105793997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                    }
105892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                }
105992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            }
1060edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
10613559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    }
1062edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
10633559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    /*
10643559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian     * Perform our own transaction if needed
10653559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian     */
1066edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1067cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    const LayerVector& previousLayers(mDrawingState.layersSortedByZ);
1068cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (currentLayers.size() > previousLayers.size()) {
10693559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        // layers have been added
10703559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        mVisibleRegionsDirty = true;
10713559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    }
10723559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian
10733559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    // some layers might have been removed, so
10743559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    // we need to update the regions they're exposing.
10753559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    if (mLayersRemoved) {
10763559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        mLayersRemoved = false;
10773559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        mVisibleRegionsDirty = true;
10783559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        const size_t count = previousLayers.size();
10793559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        for (size_t i=0 ; i<count ; i++) {
10803559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian            const sp<LayerBase>& layer(previousLayers[i]);
10813559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian            if (currentLayers.indexOf(layer) < 0) {
10823559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                // this layer is not visible anymore
10833559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                // TODO: we could traverse the tree from front to back and
10843559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                //       compute the actual visible region
10853559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                // TODO: we could cache the transformed region
10861501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian                const Layer::State& s(layer->drawingState());
10871501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian                Region visibleReg = s.transform.transform(
10881501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian                        Region(Rect(s.active.w, s.active.h)));
10891501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian                invalidateLayerStack(s.layerStack, visibleReg);
10900aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            }
1091edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1092edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1093edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1094edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    commitTransaction();
10954fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
10964fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
10974fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::commitTransaction()
10984fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian{
10994fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    if (!mLayersPendingRemoval.isEmpty()) {
11004fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // Notify removed layers now that they can't be drawn from
11014fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        for (size_t i = 0; i < mLayersPendingRemoval.size(); i++) {
11024fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            mLayersPendingRemoval[i]->onRemoved();
11034fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        }
11044fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        mLayersPendingRemoval.clear();
11054fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
11064fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
11074fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mDrawingState = mCurrentState;
11084fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mTransationPending = false;
11094fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mTransactionCV.broadcast();
1110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::computeVisibleRegions(
111387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const LayerVector& currentLayers, uint32_t layerStack,
111487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        Region& outDirtyRegion, Region& outOpaqueRegion)
1115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1116841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
1117841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
1118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveOpaqueLayers;
1119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveCoveredLayers;
1120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region dirty;
1121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
112287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    outDirtyRegion.clear();
1123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t i = currentLayers.size();
1125edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    while (i--) {
1126076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        const sp<LayerBase>& layer = currentLayers[i];
1127edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // start with the whole surface at its current location
1129970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian        const Layer::State& s(layer->drawingState());
1130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
113187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        // only consider the layers on the given later stack
113287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        if (s.layerStack != layerStack)
113387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            continue;
113487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
1135ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
1136ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * opaqueRegion: area of a surface that is fully opaque.
1137ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
1138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region opaqueRegion;
1139ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1140ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
1141ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visibleRegion: area of a surface that is visible on screen
1142ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * and not fully transparent. This is essentially the layer's
1143ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * footprint minus the opaque regions above it.
1144ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * Areas covered by a translucent surface are considered visible.
1145ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
1146edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region visibleRegion;
1147ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1148ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
1149ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * coveredRegion: area of a surface that is covered by all
1150ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visible regions above it (which includes the translucent areas).
1151ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
1152edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region coveredRegion;
1153ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1154ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1155ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // handle hidden surfaces by setting the visible region to empty
1156da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian        if (CC_LIKELY(layer->isVisible())) {
1157a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            const bool translucent = !layer->isOpaque();
11584fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            Rect bounds(layer->computeBounds());
1159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            visibleRegion.set(bounds);
1160ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            if (!visibleRegion.isEmpty()) {
1161ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // Remove the transparent area from the visible region
1162ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (translucent) {
11634fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    Region transparentRegionScreen;
11644fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    const Transform tr(s.transform);
11654fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    if (tr.transformed()) {
11664fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                        if (tr.preserveRects()) {
11674fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            // transform the transparent region
11684fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            transparentRegionScreen = tr.transform(s.transparentRegion);
11694fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                        } else {
11704fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            // transformation too complex, can't do the
11714fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            // transparent region optimization.
11724fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            transparentRegionScreen.clear();
11734fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                        }
11744fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    } else {
11754fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                        transparentRegionScreen = s.transparentRegion;
11764fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    }
11774fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    visibleRegion.subtractSelf(transparentRegionScreen);
1178ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
1179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1180ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // compute the opaque region
11814fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                const int32_t layerOrientation = s.transform.getOrientation();
1182ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (s.alpha==255 && !translucent &&
1183ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                        ((layerOrientation & Transform::ROT_INVALID) == false)) {
1184ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    // the opaque region is the layer's footprint
1185ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    opaqueRegion = visibleRegion;
1186ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
1187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1190ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Clip the covered region to the visible region
1191ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        coveredRegion = aboveCoveredLayers.intersect(visibleRegion);
1192ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1193ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveCoveredLayers for next (lower) layer
1194ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        aboveCoveredLayers.orSelf(visibleRegion);
1195ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // subtract the opaque region covered by the layers above us
1197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        visibleRegion.subtractSelf(aboveOpaqueLayers);
1198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1199edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // compute this layer's dirty region
1200edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (layer->contentDirty) {
1201edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // we need to invalidate the whole region
1202edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dirty = visibleRegion;
1203edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // as well, as the old visible region
12044fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            dirty.orSelf(layer->visibleRegion);
1205edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->contentDirty = false;
1206edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
1207a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian            /* compute the exposed region:
1208ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   the exposed region consists of two components:
1209ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   1) what's VISIBLE now and was COVERED before
1210ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   2) what's EXPOSED now less what was EXPOSED before
1211ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
1212ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * note that (1) is conservative, we start with the whole
1213ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * visible region but only keep what used to be covered by
1214ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * something -- which mean it may have been exposed.
1215ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
1216ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * (2) handles areas that were not covered by anything but got
1217ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * exposed because of a resize.
1218a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian             */
1219ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region newExposed = visibleRegion - coveredRegion;
12204fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region oldVisibleRegion = layer->visibleRegion;
12214fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region oldCoveredRegion = layer->coveredRegion;
1222ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldExposed = oldVisibleRegion - oldCoveredRegion;
1223ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed);
1224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirty.subtractSelf(aboveOpaqueLayers);
1226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // accumulate to the screen dirty region
122887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        outDirtyRegion.orSelf(dirty);
1229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1230ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveOpaqueLayers for next (lower) layer
1231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        aboveOpaqueLayers.orSelf(opaqueRegion);
12328b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
1233edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // Store the visible region is screen space
1234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setVisibleRegion(visibleRegion);
1235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setCoveredRegion(coveredRegion);
1236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
123887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    outOpaqueRegion = aboveOpaqueLayers;
1239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
124187baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::invalidateLayerStack(uint32_t layerStack,
124287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const Region& dirty) {
124392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
12444297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
12454297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        if (hw->getLayerStack() == layerStack) {
12464297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->dirtyRegion.orSelf(dirty);
124792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        }
124892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    }
124987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian}
125087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
125187baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handlePageFlip()
1252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
12534fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    Region dirtyRegion;
125499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
12554fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    bool visibleRegions = false;
1256cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
12574fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    const size_t count = currentLayers.size();
12584fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    for (size_t i=0 ; i<count ; i++) {
1259cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
126087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const Region dirty(layer->latchBuffer(visibleRegions));
12611501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian        const Layer::State& s(layer->drawingState());
126287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        invalidateLayerStack(s.layerStack, dirty);
12634fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
12644da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
12653b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    mVisibleRegionsDirty |= visibleRegions;
1266edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1267edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1268ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopianvoid SurfaceFlinger::invalidateHwcGeometry()
1269ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian{
1270ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian    mHwWorkListDirty = true;
1271ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian}
1272ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian
127399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
1274cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doDisplayComposition(const sp<const DisplayDevice>& hw,
127587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const Region& inDirtyRegion)
1276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
127787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    Region dirtyRegion(inDirtyRegion);
127887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
1279b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // compute the invalid region
12804297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->swapRegion.orSelf(dirtyRegion);
1281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
12824297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    uint32_t flags = hw->getFlags();
12830f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian    if (flags & DisplayDevice::SWAP_RECTANGLE) {
128429d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // we can redraw only what's dirty, but since SWAP_RECTANGLE only
128529d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // takes a rectangle, we must make sure to update that whole
128629d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // rectangle in that case
12874297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        dirtyRegion.set(hw->swapRegion.bounds());
1288edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
12890f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian        if (flags & DisplayDevice::PARTIAL_UPDATES) {
129029d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // We need to redraw the rectangle that will be updated
1291df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian            // (pushed to the framebuffer).
129295a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian            // This is needed because PARTIAL_UPDATES only takes one
12930f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian            // rectangle instead of a region (see DisplayDevice::flip())
12944297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            dirtyRegion.set(hw->swapRegion.bounds());
1295edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
129629d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // we need to redraw everything (the whole screen)
12974297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            dirtyRegion.set(hw->bounds());
12984297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->swapRegion = dirtyRegion;
1299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1301edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1302cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    doComposeSurfaces(hw, dirtyRegion);
1303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
13049c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    // update the swap region and clear the dirty region
13054297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->swapRegion.orSelf(dirtyRegion);
1306da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
1307da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian    // swap buffers (presentation)
1308da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian    hw->swapBuffers(getHwComposer());
1309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1310edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1311cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& hw, const Region& dirty)
1312edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
131385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    const int32_t id = hw->getHwcDisplayId();
13148630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    HWComposer& hwc(getHwComposer());
13151e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian    HWComposer::LayerListIterator cur = hwc.begin(id);
13161e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian    const HWComposer::LayerListIterator end = hwc.end(id);
1317a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
131885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    const bool hasGlesComposition = hwc.hasGlesComposition(id) || (cur==end);
131985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    if (hasGlesComposition) {
1320da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian        DisplayDevice::makeCurrent(mEGLDisplay, hw, mEGLContext);
1321a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
132252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        // set the frame buffer
132352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        glMatrixMode(GL_MODELVIEW);
132452bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        glLoadIdentity();
1325a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
1326a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        // Never touch the framebuffer if we don't have any framebuffer layers
132785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        const bool hasHwcComposition = hwc.hasHwcComposition(id);
1328e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian        if (hasHwcComposition) {
1329b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // when using overlays, we assume a fully transparent framebuffer
1330b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // NOTE: we could reduce how much we need to clear, for instance
1331b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // remove where there are opaque FB layers. however, on some
1332b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // GPUs doing a "clean slate" glClear might be more efficient.
1333b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // We'll revisit later if needed.
1334b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            glClearColor(0, 0, 0, 0);
1335b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            glClear(GL_COLOR_BUFFER_BIT);
1336b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian        } else {
13374297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            const Region region(hw->undefinedRegion.intersect(dirty));
1338b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // screen is already cleared here
133987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            if (!region.isEmpty()) {
1340b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                // can happen with SurfaceView
134155801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian                drawWormhole(hw, region);
1342b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            }
1343a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        }
134485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    }
13454b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian
134685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    /*
134785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian     * and then, render the layers targeted at the framebuffer
134885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian     */
13494b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian
135085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    const Vector< sp<LayerBase> >& layers(hw->getVisibleLayersSortedByZ());
135185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    const size_t count = layers.size();
135285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    const Transform& tr = hw->getTransform();
135385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    if (cur != end) {
135485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        // we're using h/w composer
135585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        for (size_t i=0 ; i<count && cur!=end ; ++i, ++cur) {
1356a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian            const sp<LayerBase>& layer(layers[i]);
13574fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region clip(dirty.intersect(tr.transform(layer->visibleRegion)));
135885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            if (!clip.isEmpty()) {
135985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                switch (cur->getCompositionType()) {
136085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                    case HWC_OVERLAY: {
136185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                        if ((cur->getHints() & HWC_HINT_CLEAR_FB)
136285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                                && i
136385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                                && layer->isOpaque()
136485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                                && hasGlesComposition) {
1365cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            // never clear the very first layer since we're
1366cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            // guaranteed the FB is already cleared
1367cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            layer->clearWithOpenGL(hw, clip);
1368cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                        }
136985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                        break;
137085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                    }
137185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                    case HWC_FRAMEBUFFER: {
1372cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                        layer->draw(hw, clip);
137385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                        break;
1374a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                    }
1375da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                    case HWC_FRAMEBUFFER_TARGET: {
1376da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                        // this should not happen as the iterator shouldn't
1377da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                        // let us get there.
1378da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                        ALOGW("HWC_FRAMEBUFFER_TARGET found in hwc list (index=%d)", i);
1379da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                        break;
1380da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                    }
1381cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                }
1382a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall            }
138385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            layer->setAcquireFence(hw, *cur);
138485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        }
138585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    } else {
138685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        // we're not using h/w composer
138785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        for (size_t i=0 ; i<count ; ++i) {
138885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            const sp<LayerBase>& layer(layers[i]);
138985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            const Region clip(dirty.intersect(
139085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                    tr.transform(layer->visibleRegion)));
139185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            if (!clip.isEmpty()) {
139285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                layer->draw(hw, clip);
139385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            }
13944b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian        }
13954b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian    }
1396edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1397edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
139855801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopianvoid SurfaceFlinger::drawWormhole(const sp<const DisplayDevice>& hw,
139955801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian        const Region& region) const
1400edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1401f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    glDisable(GL_TEXTURE_EXTERNAL_OES);
1402b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian    glDisable(GL_TEXTURE_2D);
1403f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    glDisable(GL_BLEND);
1404b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian    glColor4f(0,0,0,0);
1405f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian
140655801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian    const int32_t height = hw->getHeight();
1407f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    Region::const_iterator it = region.begin();
1408f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    Region::const_iterator const end = region.end();
1409f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    while (it != end) {
1410f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        const Rect& r = *it++;
141155801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian        GLfloat vertices[][2] = {
141255801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian                { r.left,  height - r.top },
141355801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian                { r.left,  height - r.bottom },
141455801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian                { r.right, height - r.bottom },
141555801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian                { r.right, height - r.top }
141655801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian        };
141755801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian        glVertexPointer(2, GL_FLOAT, 0, vertices);
1418f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1419f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    }
1420edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1421edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
142296f0819f81293076e652792794a961543e6750d7Mathias Agopianssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
142396f0819f81293076e652792794a961543e6750d7Mathias Agopian        const sp<LayerBaseClient>& lbc)
14241b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
142596f0819f81293076e652792794a961543e6750d7Mathias Agopian    // attach this layer to the client
14264f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    size_t name = client->attachLayer(lbc);
14274f113740180b6512b43723c4728f262882dc9b45Mathias Agopian
142896f0819f81293076e652792794a961543e6750d7Mathias Agopian    // add this layer to the current state list
1429921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    Mutex::Autolock _l(mStateLock);
1430921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    mCurrentState.layersSortedByZ.add(lbc);
143196f0819f81293076e652792794a961543e6750d7Mathias Agopian
14324f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    return ssize_t(name);
143396f0819f81293076e652792794a961543e6750d7Mathias Agopian}
143496f0819f81293076e652792794a961543e6750d7Mathias Agopian
143596f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer)
143696f0819f81293076e652792794a961543e6750d7Mathias Agopian{
143796f0819f81293076e652792794a961543e6750d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
143896f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = purgatorizeLayer_l(layer);
143996f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR)
14403559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        setTransactionFlags(eTransactionNeeded);
144196f0819f81293076e652792794a961543e6750d7Mathias Agopian    return err;
1442edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1443edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1444076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase)
1445edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1446edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase);
1447edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (index >= 0) {
1448076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved = true;
1449edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
1450edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
14513d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    return status_t(index);
1452edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1453edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
14549a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase)
14559a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
145676cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    // First add the layer to the purgatory list, which makes sure it won't
145776cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    // go away, then remove it from the main list (through a transaction).
14589a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    ssize_t err = removeLayer_l(layerBase);
145976cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    if (err >= 0) {
146076cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian        mLayerPurgatory.add(layerBase);
146176cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    }
14628c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian
14632f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall    mLayersPendingRemoval.push(layerBase);
14640b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian
14653d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // it's possible that we don't find a layer, because it might
14663d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // have been destroyed already -- this is not technically an error
146796f0819f81293076e652792794a961543e6750d7Mathias Agopian    // from the user because there is a race between Client::destroySurface(),
146896f0819f81293076e652792794a961543e6750d7Mathias Agopian    // ~Client() and ~ISurface().
14699a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err;
14709a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
14719a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
1472dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopianuint32_t SurfaceFlinger::peekTransactionFlags(uint32_t flags)
1473dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian{
1474dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian    return android_atomic_release_load(&mTransactionFlags);
1475dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian}
1476dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian
1477edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags)
1478edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1479edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return android_atomic_and(~flags, &mTransactionFlags) & flags;
1480edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1481edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1482bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags)
1483edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1484edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t old = android_atomic_or(flags, &mTransactionFlags);
1485edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((old & flags)==0) { // wake the server up
148699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        signalTransaction();
1487edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1488edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return old;
1489edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1490edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
14918b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopianvoid SurfaceFlinger::setTransactionState(
14928b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        const Vector<ComposerState>& state,
14938b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        const Vector<DisplayState>& displays,
14948b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        uint32_t flags)
14958b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian{
1496698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
149728378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    uint32_t transactionFlags = 0;
1498e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
1499e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    size_t count = displays.size();
1500e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
1501e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const DisplayState& s(displays[i]);
1502e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        transactionFlags |= setDisplayStateLocked(s);
1503b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis    }
1504b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis
1505e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    count = state.size();
1506698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
1507698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const ComposerState& s(state[i]);
1508698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        sp<Client> client( static_cast<Client *>(s.client.get()) );
150928378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        transactionFlags |= setClientStateLocked(client, s.state);
1510698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    }
1511386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian
151228378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    if (transactionFlags) {
1513386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // this triggers the transaction
151428378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        setTransactionFlags(transactionFlags);
1515698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian
1516386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // if this is a synchronous transaction, wait for it to take effect
1517386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // before returning.
1518386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        if (flags & eSynchronous) {
1519386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            mTransationPending = true;
1520386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        }
1521386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        while (mTransationPending) {
1522386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
1523386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            if (CC_UNLIKELY(err != NO_ERROR)) {
1524386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                // just in case something goes wrong in SF, return to the
1525386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                // called after a few seconds.
152632397c1cd3327905173b36baa6fd1c579bc328ffSteve Block                ALOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!");
1527386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                mTransationPending = false;
1528386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                break;
1529386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            }
1530cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        }
1531edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1532edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1533edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1534e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setDisplayStateLocked(const DisplayState& s)
1535e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{
1536e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    uint32_t flags = 0;
1537e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    DisplayDeviceState& disp(mCurrentState.displays.editValueFor(s.token));
15383ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    if (disp.isValid()) {
1539e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const uint32_t what = s.what;
1540e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & DisplayState::eSurfaceChanged) {
1541e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.surface->asBinder() != s.surface->asBinder()) {
1542e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.surface = s.surface;
1543e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
1544e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1545e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1546e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & DisplayState::eLayerStackChanged) {
1547e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.layerStack != s.layerStack) {
1548e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.layerStack = s.layerStack;
1549e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
1550e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1551e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
155200e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian        if (what & DisplayState::eDisplayProjectionChanged) {
1553e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.orientation != s.orientation) {
1554e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.orientation = s.orientation;
1555e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
1556e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1557e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.frame != s.frame) {
1558e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.frame = s.frame;
1559e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
1560e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1561e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.viewport != s.viewport) {
1562e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.viewport = s.viewport;
1563e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
1564e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1565e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1566e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
1567e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return flags;
1568e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
1569e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
1570e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setClientStateLocked(
1571e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const sp<Client>& client,
1572e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const layer_state_t& s)
1573e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{
1574e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    uint32_t flags = 0;
1575e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    sp<LayerBaseClient> layer(client->getLayerUser(s.surface));
1576e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    if (layer != 0) {
1577e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const uint32_t what = s.what;
1578e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::ePositionChanged) {
1579e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setPosition(s.x, s.y))
1580e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1581e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1582e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eLayerChanged) {
1583e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            // NOTE: index needs to be calculated before we update the state
1584e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
1585e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setLayer(s.z)) {
1586e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.removeAt(idx);
1587e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.add(layer);
1588e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // we need traversal (state changed)
1589e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // AND transaction (list changed)
1590e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTransactionNeeded|eTraversalNeeded;
1591e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1592e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1593e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eSizeChanged) {
1594e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setSize(s.w, s.h)) {
1595e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1596e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1597e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1598e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eAlphaChanged) {
1599e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f)))
1600e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1601e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1602e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eMatrixChanged) {
1603e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setMatrix(s.matrix))
1604e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1605e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1606e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eTransparentRegionChanged) {
1607e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setTransparentRegionHint(s.transparentRegion))
1608e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1609e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1610e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eVisibilityChanged) {
1611e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setFlags(s.flags, s.mask))
1612e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1613e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1614e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eCropChanged) {
1615e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setCrop(s.crop))
1616e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1617e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1618e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eLayerStackChanged) {
1619e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            // NOTE: index needs to be calculated before we update the state
1620e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
1621e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setLayerStack(s.layerStack)) {
1622e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.removeAt(idx);
1623e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.add(layer);
1624e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // we need traversal (state changed)
1625e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // AND transaction (list changed)
1626e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTransactionNeeded|eTraversalNeeded;
1627e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1628e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1629e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
1630e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return flags;
1631e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
1632e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
1633921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopiansp<ISurface> SurfaceFlinger::createLayer(
16340ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        ISurfaceComposerClient::surface_data_t* params,
16350ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const String8& name,
16360ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const sp<Client>& client,
16373ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian       uint32_t w, uint32_t h, PixelFormat format,
1638edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t flags)
1639edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1640076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBaseClient> layer;
1641a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    sp<ISurface> surfaceHandle;
16426e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian
16436e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    if (int32_t(w|h) < 0) {
1644921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        ALOGE("createLayer() failed, w or h is negative (w=%d, h=%d)",
16456e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian                int(w), int(h));
16466e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian        return surfaceHandle;
16476e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    }
16488b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
1649921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    //ALOGD("createLayer for (%d x %d), name=%s", w, h, name.string());
16503165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian    switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {
16513165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        case ISurfaceComposerClient::eFXSurfaceNormal:
16523ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian            layer = createNormalLayer(client, w, h, flags, format);
1653edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
16543165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        case ISurfaceComposerClient::eFXSurfaceBlur:
16553165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        case ISurfaceComposerClient::eFXSurfaceDim:
16563ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian            layer = createDimLayer(client, w, h, flags);
1657edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
16583165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        case ISurfaceComposerClient::eFXSurfaceScreenshot:
16593ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian            layer = createScreenshotLayer(client, w, h, flags);
1660118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian            break;
1661edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1662edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1663076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (layer != 0) {
166496f0819f81293076e652792794a961543e6750d7Mathias Agopian        layer->initStates(w, h, flags);
1665285dbde2e0cd0057be070ded3be8f5f453147edcMathias Agopian        layer->setName(name);
166696f0819f81293076e652792794a961543e6750d7Mathias Agopian        ssize_t token = addClientLayer(client, layer);
1667edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        surfaceHandle = layer->getSurface();
16688b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber        if (surfaceHandle != 0) {
166996f0819f81293076e652792794a961543e6750d7Mathias Agopian            params->token = token;
1670a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            params->identity = layer->getIdentity();
16711c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        }
167296f0819f81293076e652792794a961543e6750d7Mathias Agopian        setTransactionFlags(eTransactionNeeded);
1673edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1674edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1675edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return surfaceHandle;
1676edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1677edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1678921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopiansp<Layer> SurfaceFlinger::createNormalLayer(
16793ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian        const sp<Client>& client,
168096f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags,
16811c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        PixelFormat& format)
1682edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1683edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize the surfaces
168492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    switch (format) {
1685edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSPARENT:
1686edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSLUCENT:
1687edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        format = PIXEL_FORMAT_RGBA_8888;
1688edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1689edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_OPAQUE:
1690a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888
1691a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian        format = PIXEL_FORMAT_RGB_565;
1692a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#else
16938f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian        format = PIXEL_FORMAT_RGBX_8888;
1694a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif
1695edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1696edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1697edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1698a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888
1699a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian    if (format == PIXEL_FORMAT_RGBX_8888)
1700a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian        format = PIXEL_FORMAT_RGBA_8888;
1701a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif
1702a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian
17033ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    sp<Layer> layer = new Layer(this, client);
1704f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian    status_t err = layer->setBuffers(w, h, format, flags);
170599ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten    if (CC_LIKELY(err != NO_ERROR)) {
1706921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        ALOGE("createNormalLayer() failed (%s)", strerror(-err));
1707076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        layer.clear();
1708edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1709edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1710edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1711edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1712921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopiansp<LayerDim> SurfaceFlinger::createDimLayer(
17133ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian        const sp<Client>& client,
171496f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags)
1715edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
17163ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    sp<LayerDim> layer = new LayerDim(this, client);
1717118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    return layer;
1718118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
1719118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
1720921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopiansp<LayerScreenshot> SurfaceFlinger::createScreenshotLayer(
17213ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian        const sp<Client>& client,
1722118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags)
1723118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{
17243ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    sp<LayerScreenshot> layer = new LayerScreenshot(this, client);
1725edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1726edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1727edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1728921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianstatus_t SurfaceFlinger::onLayerRemoved(const sp<Client>& client, SurfaceID sid)
17299a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
17309a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    /*
17319a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     * called by the window manager, when a surface should be marked for
17329a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     * destruction.
17338b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber     *
17340aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * The surface is removed from the current and drawing lists, but placed
17350aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * in the purgatory queue, so it's not destroyed right-away (we need
17360aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * to wait for all client's references to go away first).
17379a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     */
17389a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
173948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    status_t err = NAME_NOT_FOUND;
17400aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian    Mutex::Autolock _l(mStateLock);
174196f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<LayerBaseClient> layer = client->getLayerUser(sid);
1742b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam
174348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    if (layer != 0) {
174448d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        err = purgatorizeLayer_l(layer);
174548d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        if (err == NO_ERROR) {
174613233e067b8f71adc3a0ade5f442265e1f27084bMathias Agopian            setTransactionFlags(eTransactionNeeded);
174748d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        }
17489a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    }
17499a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return err;
17509a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
17519a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
1752921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianstatus_t SurfaceFlinger::onLayerDestroyed(const wp<LayerBaseClient>& layer)
1753edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1754759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian    // called by ~ISurface() when all references are gone
1755ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    status_t err = NO_ERROR;
1756ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    sp<LayerBaseClient> l(layer.promote());
1757ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    if (l != NULL) {
1758ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        Mutex::Autolock _l(mStateLock);
1759ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        err = removeLayer_l(l);
1760ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        if (err == NAME_NOT_FOUND) {
1761ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // The surface wasn't in the current list, which means it was
1762ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // removed already, which means it is in the purgatory,
1763ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // and need to be removed from there.
1764ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            ssize_t idx = mLayerPurgatory.remove(l);
1765e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block            ALOGE_IF(idx < 0,
1766ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian                    "layer=%p is not in the purgatory list", l.get());
1767f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        }
1768e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE_IF(err<0 && err != NAME_NOT_FOUND,
1769ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian                "error removing layer=%p (%s)", l.get(), strerror(-err));
1770ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    }
1771ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    return err;
1772edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1773edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1774b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// ---------------------------------------------------------------------------
1775b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
177613a082e160c2d1d8006b93a555a57035213d568bAndy McFaddenvoid SurfaceFlinger::onInitializeDisplays() {
177713a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    // reset screen orientation
177813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    Vector<ComposerState> state;
177913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    Vector<DisplayState> displays;
178013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    DisplayState d;
178100e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian    d.what = DisplayState::eDisplayProjectionChanged;
17823ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    d.token = mDefaultDisplays[DisplayDevice::DISPLAY_PRIMARY];
178313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    d.orientation = DisplayState::eOrientationDefault;
17844c05dd175ee3bd5119eecf368742b6510a8cfa6cJeff Brown    d.frame.makeInvalid();
17854c05dd175ee3bd5119eecf368742b6510a8cfa6cJeff Brown    d.viewport.makeInvalid();
178613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    displays.add(d);
178713a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    setTransactionState(state, displays, 0);
1788cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian    onScreenAcquired(getDefaultDisplayDevice());
178913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden}
179013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
179113a082e160c2d1d8006b93a555a57035213d568bAndy McFaddenvoid SurfaceFlinger::initializeDisplays() {
179213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    class MessageScreenInitialized : public MessageBase {
179313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden        SurfaceFlinger* flinger;
179413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    public:
179513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden        MessageScreenInitialized(SurfaceFlinger* flinger) : flinger(flinger) { }
179613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden        virtual bool handler() {
179713a082e160c2d1d8006b93a555a57035213d568bAndy McFadden            flinger->onInitializeDisplays();
179813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden            return true;
179913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden        }
180013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    };
180113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    sp<MessageBase> msg = new MessageScreenInitialized(this);
180213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    postMessageAsync(msg);  // we may be called from main thread, use async message
180313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden}
180413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
180513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
1806cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopianvoid SurfaceFlinger::onScreenAcquired(const sp<const DisplayDevice>& hw) {
18078e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross    ALOGD("Screen about to return, flinger = %p", this);
18088630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    getHwComposer().acquire();
18094297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->acquireScreen();
1810cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian    if (hw->getDisplayType() == DisplayDevice::DISPLAY_PRIMARY) {
1811cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian        // FIXME: eventthread only knows about the main display right now
1812cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian        mEventThread->onScreenAcquired();
1813cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian    }
181420128300e0cb7f459a60cfbcddb48190ce6545edMathias Agopian    mVisibleRegionsDirty = true;
181520128300e0cb7f459a60cfbcddb48190ce6545edMathias Agopian    repaintEverything();
1816edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1817edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1818cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopianvoid SurfaceFlinger::onScreenReleased(const sp<const DisplayDevice>& hw) {
18198e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross    ALOGD("About to give-up screen, flinger = %p", this);
18204297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    if (hw->isScreenAcquired()) {
1821cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian        if (hw->getDisplayType() == DisplayDevice::DISPLAY_PRIMARY) {
1822cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian            // FIXME: eventthread only knows about the main display right now
1823cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian            mEventThread->onScreenReleased();
1824cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian        }
18254297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        hw->releaseScreen();
18268630320433bd15aca239522e54e711ef6372ab07Mathias Agopian        getHwComposer().release();
1827ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian        mVisibleRegionsDirty = true;
1828b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        // from this point on, SF will stop drawing
1829b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    }
1830b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian}
1831b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
18328e533069e5721e55cb9768e140e16546c3a4a8b6Colin Crossvoid SurfaceFlinger::unblank() {
1833b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    class MessageScreenAcquired : public MessageBase {
1834b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        SurfaceFlinger* flinger;
1835b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    public:
1836b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        MessageScreenAcquired(SurfaceFlinger* flinger) : flinger(flinger) { }
1837b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        virtual bool handler() {
1838cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian            // FIXME: should this be per-display?
1839cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian            flinger->onScreenAcquired(flinger->getDefaultDisplayDevice());
1840b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            return true;
1841b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        }
1842b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    };
1843b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    sp<MessageBase> msg = new MessageScreenAcquired(this);
1844b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    postMessageSync(msg);
1845edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1846edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
18478e533069e5721e55cb9768e140e16546c3a4a8b6Colin Crossvoid SurfaceFlinger::blank() {
1848b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    class MessageScreenReleased : public MessageBase {
1849b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        SurfaceFlinger* flinger;
1850b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    public:
1851b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        MessageScreenReleased(SurfaceFlinger* flinger) : flinger(flinger) { }
1852b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        virtual bool handler() {
1853cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian            // FIXME: should this be per-display?
1854cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian            flinger->onScreenReleased(flinger->getDefaultDisplayDevice());
1855b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            return true;
1856b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        }
1857b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    };
1858b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    sp<MessageBase> msg = new MessageScreenReleased(this);
1859b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    postMessageSync(msg);
1860b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian}
1861b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
1862b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// ---------------------------------------------------------------------------
1863b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
1864edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
1865edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
18661d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling    const size_t SIZE = 4096;
1867edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char buffer[SIZE];
1868edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    String8 result;
186999b49840d309727678b77403d6cc9f920111623fMathias Agopian
187099b49840d309727678b77403d6cc9f920111623fMathias Agopian    if (!PermissionCache::checkCallingPermission(sDump)) {
1871edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        snprintf(buffer, SIZE, "Permission Denial: "
1872edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                "can't dump SurfaceFlinger from pid=%d, uid=%d\n",
1873edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                IPCThreadState::self()->getCallingPid(),
1874edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                IPCThreadState::self()->getCallingUid());
1875edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        result.append(buffer);
1876edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
18779795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // Try to get the main lock, but don't insist if we can't
18789795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // (this would indicate SF is stuck, but we want to be able to
18799795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // print something in dumpsys).
18809795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        int retry = 3;
18819795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        while (mStateLock.tryLock()<0 && --retry>=0) {
18829795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            usleep(1000000);
18839795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
18849795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const bool locked(retry >= 0);
18859795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (!locked) {
18868b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber            snprintf(buffer, SIZE,
18879795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "SurfaceFlinger appears to be unresponsive, "
18889795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "dumping anyways (no locks held)\n");
18899795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            result.append(buffer);
18909795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
18919795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
189282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        bool dumpAll = true;
189382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        size_t index = 0;
189425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        size_t numArgs = args.size();
189525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        if (numArgs) {
189625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
189725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--list"))) {
189825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                index++;
189925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                listLayersLocked(args, index, result, buffer, SIZE);
190035aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
190125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            }
190225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
190325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
190425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--latency"))) {
190582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                index++;
190682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                dumpStatsLocked(args, index, result, buffer, SIZE);
190735aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
190882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            }
190925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
191025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
191125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--latency-clear"))) {
191225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                index++;
191325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                clearStatsLocked(args, index, result, buffer, SIZE);
191435aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
191525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            }
1916edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
19171b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
191882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (dumpAll) {
191982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            dumpAllLocked(result, buffer, SIZE);
192082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
192148b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
192282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (locked) {
192382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mStateLock.unlock();
192448b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        }
192582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
192682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    write(fd, result.string(), result.size());
192782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    return NO_ERROR;
192882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
192948b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
193025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::listLayersLocked(const Vector<String16>& args, size_t& index,
193125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        String8& result, char* buffer, size_t SIZE) const
193225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
193325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
193425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const size_t count = currentLayers.size();
193525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
193625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
193725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        snprintf(buffer, SIZE, "%s\n", layer->getName().string());
193825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        result.append(buffer);
193925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
194025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
194125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
194282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index,
194382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        String8& result, char* buffer, size_t SIZE) const
194482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
194582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    String8 name;
194682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    if (index < args.size()) {
194782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        name = String8(args[index]);
194882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        index++;
194982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
195048b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
195182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
195282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const size_t count = currentLayers.size();
195382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    for (size_t i=0 ; i<count ; i++) {
195482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
195582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (name.isEmpty()) {
195682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            snprintf(buffer, SIZE, "%s\n", layer->getName().string());
195782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            result.append(buffer);
195882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
195982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (name.isEmpty() || (name == layer->getName())) {
196082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            layer->dumpStats(result, buffer, SIZE);
196182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
196282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
196382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
1964ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian
196525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& index,
196625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        String8& result, char* buffer, size_t SIZE) const
196725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
196825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    String8 name;
196925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    if (index < args.size()) {
197025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        name = String8(args[index]);
197125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        index++;
197225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
197325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
197425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
197525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const size_t count = currentLayers.size();
197625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
197725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
197825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        if (name.isEmpty() || (name == layer->getName())) {
197925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            layer->clearStats();
198025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        }
198125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
198225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
198325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
198482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpAllLocked(
198582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        String8& result, char* buffer, size_t SIZE) const
198682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
198782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    // figure out if we're stuck somewhere
198882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t now = systemTime();
198982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t inSwapBuffers(mDebugInSwapBuffers);
199082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t inTransaction(mDebugInTransaction);
199182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0;
199282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0;
1993bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
199482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
199582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump the visible layer list
199682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
199782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
199882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const size_t count = currentLayers.size();
199982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "Visible layers (count = %d)\n", count);
200082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
200182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    for (size_t i=0 ; i<count ; i++) {
200282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
200382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        layer->dump(result, buffer, SIZE);
200482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
2005bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
200682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
200782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump the layers in the purgatory
200882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
2009ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian
201082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const size_t purgatorySize = mLayerPurgatory.size();
201182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "Purgatory state (%d entries)\n", purgatorySize);
201282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
201382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    for (size_t i=0 ; i<purgatorySize ; i++) {
201482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
201582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        layer->shortDump(result, buffer, SIZE);
201682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
20171b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
201882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
20195f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian     * Dump Display state
20205f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian     */
20215f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian
20225f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
20235f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        const sp<const DisplayDevice>& hw(mDisplays[dpy]);
20245f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        snprintf(buffer, SIZE,
20255f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian                "+ DisplayDevice[%u]\n"
20264fb3999cea652617be5125f8a42c257467bf3c77Jeff Brown                "   type=%x, layerStack=%u, (%4dx%4d), orient=%2d (type=%08x), "
20276e220a6ce6971555b883f4852c6e5d4c7a617815Jeff Brown                "flips=%u, secure=%d, numLayers=%u, v:[%d,%d,%d,%d], f:[%d,%d,%d,%d], "
20286e220a6ce6971555b883f4852c6e5d4c7a617815Jeff Brown                "transform:[[%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f]]\n",
20295f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian                dpy,
20303ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian                hw->getDisplayType(), hw->getLayerStack(),
20315f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian                hw->getWidth(), hw->getHeight(),
20325f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian                hw->getOrientation(), hw->getTransform().getType(),
20335f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian                hw->getPageFlipCount(),
20345f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian                hw->getSecureLayerVisible(),
2035da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian                hw->getVisibleLayersSortedByZ().size(),
2036da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian                hw->getViewport().left, hw->getViewport().top, hw->getViewport().right, hw->getViewport().bottom,
20376e220a6ce6971555b883f4852c6e5d4c7a617815Jeff Brown                hw->getFrame().left, hw->getFrame().top, hw->getFrame().right, hw->getFrame().bottom,
20386e220a6ce6971555b883f4852c6e5d4c7a617815Jeff Brown                hw->getTransform()[0][0], hw->getTransform()[1][0], hw->getTransform()[2][0],
20396e220a6ce6971555b883f4852c6e5d4c7a617815Jeff Brown                hw->getTransform()[0][1], hw->getTransform()[1][1], hw->getTransform()[2][1],
20406e220a6ce6971555b883f4852c6e5d4c7a617815Jeff Brown                hw->getTransform()[0][2], hw->getTransform()[1][2], hw->getTransform()[2][2]);
2041da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian
20425f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        result.append(buffer);
20435f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    }
20445f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian
20455f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    /*
204682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump SurfaceFlinger global state
204782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
20481b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
204982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "SurfaceFlinger global state:\n");
205082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
20511b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
2052888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian    HWComposer& hwc(getHwComposer());
20534297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    sp<const DisplayDevice> hw(getDefaultDisplayDevice());
205482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const GLExtensions& extensions(GLExtensions::getInstance());
205582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "GLES: %s, %s, %s\n",
205682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            extensions.getVendor(),
205782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            extensions.getRenderer(),
205882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            extensions.getVersion());
205982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
2060d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
206182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "EGL : %s\n",
2062d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian            eglQueryString(mEGLDisplay, EGL_VERSION_HW_ANDROID));
206382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
206473d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian
206582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "EXTS: %s\n", extensions.getExtension());
206682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
20679795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
20684297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->undefinedRegion.dump(result, "undefinedRegion");
206982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE,
207082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  orientation=%d, canDraw=%d\n",
20714297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->getOrientation(), hw->canDraw());
207282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
207382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE,
207482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  last eglSwapBuffers() time: %f us\n"
207582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  last transaction time     : %f us\n"
2076c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian            "  transaction-flags         : %08x\n"
207782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  refresh-rate              : %f fps\n"
207882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  x-dpi                     : %f\n"
20798b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            "  y-dpi                     : %f\n",
208082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mLastSwapBufferTime/1000.0,
208182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mLastTransactionTime/1000.0,
2082c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian            mTransactionFlags,
2083b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden            1e9 / hwc.getRefreshPeriod(HWC_DISPLAY_PRIMARY),
2084b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden            hwc.getDpiX(HWC_DISPLAY_PRIMARY),
2085b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden            hwc.getDpiY(HWC_DISPLAY_PRIMARY));
208682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
208782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
208882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "  eglSwapBuffers time: %f us\n",
208982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            inSwapBuffersDuration/1000.0);
209082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
209182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
209282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "  transaction time: %f us\n",
209382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            inTransactionDuration/1000.0);
209482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
209582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
209682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
209782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * VSYNC state
209882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
209982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    mEventThread->dump(result, buffer, SIZE);
210082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
210182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
210282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump HWComposer state
210382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
210482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "h/w composer state:\n");
210582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
210682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "  h/w composer %s and %s\n",
210782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            hwc.initCheck()==NO_ERROR ? "present" : "not present",
210882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                    (mDebugDisableHWC || mDebugRegion) ? "disabled" : "enabled");
210982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
21104297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hwc.dump(result, buffer, SIZE, hw->getVisibleLayersSortedByZ());
211182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
211282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
211382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump gralloc state
211482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
211582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
211682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    alloc.dump(result);
21174297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->dump(result);
2118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
212063f165fd6b86d04be94d4023e845e98560504a96Keun young Parkbool SurfaceFlinger::startDdmConnection()
212163f165fd6b86d04be94d4023e845e98560504a96Keun young Park{
212263f165fd6b86d04be94d4023e845e98560504a96Keun young Park    void* libddmconnection_dso =
212363f165fd6b86d04be94d4023e845e98560504a96Keun young Park            dlopen("libsurfaceflinger_ddmconnection.so", RTLD_NOW);
212463f165fd6b86d04be94d4023e845e98560504a96Keun young Park    if (!libddmconnection_dso) {
212563f165fd6b86d04be94d4023e845e98560504a96Keun young Park        return false;
212663f165fd6b86d04be94d4023e845e98560504a96Keun young Park    }
212763f165fd6b86d04be94d4023e845e98560504a96Keun young Park    void (*DdmConnection_start)(const char* name);
212863f165fd6b86d04be94d4023e845e98560504a96Keun young Park    DdmConnection_start =
212963f165fd6b86d04be94d4023e845e98560504a96Keun young Park            (typeof DdmConnection_start)dlsym(libddmconnection_dso, "DdmConnection_start");
213063f165fd6b86d04be94d4023e845e98560504a96Keun young Park    if (!DdmConnection_start) {
213163f165fd6b86d04be94d4023e845e98560504a96Keun young Park        dlclose(libddmconnection_dso);
213263f165fd6b86d04be94d4023e845e98560504a96Keun young Park        return false;
213363f165fd6b86d04be94d4023e845e98560504a96Keun young Park    }
213463f165fd6b86d04be94d4023e845e98560504a96Keun young Park    (*DdmConnection_start)(getServiceName());
213563f165fd6b86d04be94d4023e845e98560504a96Keun young Park    return true;
213663f165fd6b86d04be94d4023e845e98560504a96Keun young Park}
213763f165fd6b86d04be94d4023e845e98560504a96Keun young Park
2138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::onTransact(
2139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
2140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2141edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (code) {
2142edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case CREATE_CONNECTION:
2143698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        case SET_TRANSACTION_STATE:
2144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case BOOT_FINISHED:
21458e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross        case BLANK:
21468e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross        case UNBLANK:
2147edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        {
2148edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // codes that require permission check
2149edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            IPCThreadState* ipc = IPCThreadState::self();
2150edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int pid = ipc->getCallingPid();
2151a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian            const int uid = ipc->getCallingUid();
215299b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
215399b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) {
2154e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block                ALOGE("Permission Denial: "
2155375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                        "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
2156375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                return PERMISSION_DENIED;
2157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
21581b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
21591b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
21601b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        case CAPTURE_SCREEN:
21611b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
21621b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            // codes that require permission check
21631b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
21641b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int pid = ipc->getCallingPid();
21651b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int uid = ipc->getCallingUid();
216699b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
216799b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) {
2168e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block                ALOGE("Permission Denial: "
21691b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                        "can't read framebuffer pid=%d, uid=%d", pid, uid);
21701b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                return PERMISSION_DENIED;
21711b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            }
21721b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
2173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
2174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
21751b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
2176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
2177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
2178b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        CHECK_INTERFACE(ISurfaceComposer, data, reply);
217999ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten        if (CC_UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) {
2180375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
2181375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int pid = ipc->getCallingPid();
2182375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int uid = ipc->getCallingUid();
2183e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block            ALOGE("Permission Denial: "
2184375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                    "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
2185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return PERMISSION_DENIED;
2186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
2187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int n;
2188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        switch (code) {
218901b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian            case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE
219035b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian            case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE
2191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
2192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1002:  // SHOW_UPDATES
2193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                n = data.readInt32();
2194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDebugRegion = n ? n : (mDebugRegion ? 0 : 1);
219553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
219653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
2197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
2198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1004:{ // repaint everything
219953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
2200cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
2201cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            }
2202cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            case 1005:{ // force transaction
2203e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                setTransactionFlags(
2204e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        eTransactionNeeded|
2205e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        eDisplayTransactionNeeded|
2206e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        eTraversalNeeded);
2207cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
2208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
22094d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            case 1006:{ // send empty update
22104d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian                signalRefresh();
22114d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian                return NO_ERROR;
22124d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            }
221353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian            case 1008:  // toggle use of hw composer
221453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                n = data.readInt32();
221553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                mDebugDisableHWC = n ? 1 : 0;
221653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
221753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
221853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                return NO_ERROR;
2219a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian            case 1009:  // toggle use of transform hint
2220a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                n = data.readInt32();
2221a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                mDebugDisableTransformHint = n ? 1 : 0;
2222a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                invalidateHwcGeometry();
2223a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                repaintEverything();
2224a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                return NO_ERROR;
2225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1010:  // interrogate.
222601b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian                reply->writeInt32(0);
2227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(0);
2228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(mDebugRegion);
2229b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                reply->writeInt32(0);
223012839bee29bdcc65731b4d42029cc59e2320c5c4Dianne Hackborn                reply->writeInt32(mDebugDisableHWC);
2231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
2232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1013: {
2233edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                Mutex::Autolock _l(mStateLock);
22344297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                sp<const DisplayDevice> hw(getDefaultDisplayDevice());
22354297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                reply->writeInt32(hw->getPageFlipCount());
2236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
2237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return NO_ERROR;
2238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
2239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return err;
2241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
224353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopianvoid SurfaceFlinger::repaintEverything() {
224487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    android_atomic_or(1, &mRepaintEverything);
224599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    signalTransaction();
224653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian}
224753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian
224859119e658a12279e8fff508f8773843de2d90917Mathias Agopian// ---------------------------------------------------------------------------
224959119e658a12279e8fff508f8773843de2d90917Mathias Agopian
22503ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopianstatus_t SurfaceFlinger::renderScreenToTexture(uint32_t layerStack,
2251118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        GLuint* textureName, GLfloat* uOut, GLfloat* vOut)
2252118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{
2253118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    Mutex::Autolock _l(mStateLock);
22543ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    return renderScreenToTextureLocked(layerStack, textureName, uOut, vOut);
2255118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
2256118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
22573ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopianstatus_t SurfaceFlinger::renderScreenToTextureLocked(uint32_t layerStack,
22589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        GLuint* textureName, GLfloat* uOut, GLfloat* vOut)
225959119e658a12279e8fff508f8773843de2d90917Mathias Agopian{
226022ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian    ATRACE_CALL();
226122ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian
226259119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
226359119e658a12279e8fff508f8773843de2d90917Mathias Agopian        return INVALID_OPERATION;
226459119e658a12279e8fff508f8773843de2d90917Mathias Agopian
226559119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // get screen geometry
22663ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    // FIXME: figure out what it means to have a screenshot texture w/ multi-display
22673ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    sp<const DisplayDevice> hw(getDefaultDisplayDevice());
22684297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const uint32_t hw_w = hw->getWidth();
22694297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const uint32_t hw_h = hw->getHeight();
227059119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLfloat u = 1;
227159119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLfloat v = 1;
227259119e658a12279e8fff508f8773843de2d90917Mathias Agopian
227359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // make sure to clear all GL error flags
227459119e658a12279e8fff508f8773843de2d90917Mathias Agopian    while ( glGetError() != GL_NO_ERROR ) ;
227559119e658a12279e8fff508f8773843de2d90917Mathias Agopian
227659119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // create a FBO
227759119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLuint name, tname;
227859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glGenTextures(1, &tname);
227959119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
2280a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2281a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
22829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
22839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            hw_w, hw_h, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
228459119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (glGetError() != GL_NO_ERROR) {
2285015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian        while ( glGetError() != GL_NO_ERROR ) ;
228659119e658a12279e8fff508f8773843de2d90917Mathias Agopian        GLint tw = (2 << (31 - clz(hw_w)));
228759119e658a12279e8fff508f8773843de2d90917Mathias Agopian        GLint th = (2 << (31 - clz(hw_h)));
22889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
22899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian                tw, th, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
229059119e658a12279e8fff508f8773843de2d90917Mathias Agopian        u = GLfloat(hw_w) / tw;
229159119e658a12279e8fff508f8773843de2d90917Mathias Agopian        v = GLfloat(hw_h) / th;
229259119e658a12279e8fff508f8773843de2d90917Mathias Agopian    }
229359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glGenFramebuffersOES(1, &name);
229459119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
22959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES,
22969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0);
229759119e658a12279e8fff508f8773843de2d90917Mathias Agopian
22989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // redraw the screen entirely...
2299c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_EXTERNAL_OES);
2300c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_2D);
23019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glClearColor(0,0,0,1);
23029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glClear(GL_COLOR_BUFFER_BIT);
2303a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glMatrixMode(GL_MODELVIEW);
2304a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glLoadIdentity();
23054297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const Vector< sp<LayerBase> >& layers(hw->getVisibleLayersSortedByZ());
23069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const size_t count = layers.size();
23079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (size_t i=0 ; i<count ; ++i) {
23089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
2309fcb239d3dac8bc80f28177f1951611c1d43286ffMathias Agopian        layer->draw(hw);
23109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
231159119e658a12279e8fff508f8773843de2d90917Mathias Agopian
23124297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->compositionComplete();
2313118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
23149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // back to main framebuffer
23159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
23169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDeleteFramebuffersOES(1, &name);
231759119e658a12279e8fff508f8773843de2d90917Mathias Agopian
23189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *textureName = tname;
23199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *uOut = u;
23209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *vOut = v;
23219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
23229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
232359119e658a12279e8fff508f8773843de2d90917Mathias Agopian
23249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// ---------------------------------------------------------------------------
23259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
23269d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brownstatus_t SurfaceFlinger::captureScreenImplLocked(const sp<IBinder>& display,
232774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        sp<IMemoryHeap>* heap,
232874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t* w, uint32_t* h, PixelFormat* f,
2329bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t sw, uint32_t sh,
2330bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ, uint32_t maxLayerZ)
233174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{
2332fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian    ATRACE_CALL();
2333fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian
233474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    status_t result = PERMISSION_DENIED;
233574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
23363b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject()) {
233774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return INVALID_OPERATION;
23383b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
233974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
234074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // get screen geometry
23413ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    sp<const DisplayDevice> hw(getDisplayDevice(display));
23424297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const uint32_t hw_w = hw->getWidth();
23434297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const uint32_t hw_h = hw->getHeight();
234474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
23453b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    // if we have secure windows on this display, never allow the screen capture
23464297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    if (hw->getSecureLayerVisible()) {
2347ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian        ALOGW("FB is protected: PERMISSION_DENIED");
23483b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        return PERMISSION_DENIED;
23493b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
23503b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
23513b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    if ((sw > hw_w) || (sh > hw_h)) {
2352ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian        ALOGE("size mismatch (%d, %d) > (%d, %d)", sw, sh, hw_w, hw_h);
235374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return BAD_VALUE;
23543b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
235574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
235674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    sw = (!sw) ? hw_w : sw;
235774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    sh = (!sh) ? hw_h : sh;
235874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const size_t size = sw * sh * 4;
2359fcb239d3dac8bc80f28177f1951611c1d43286ffMathias Agopian    const bool filtering = sw != hw_w || sh != hw_h;
236074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
2361ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian//    ALOGD("screenshot: sw=%d, sh=%d, minZ=%d, maxZ=%d",
2362ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian//            sw, sh, minLayerZ, maxLayerZ);
2363c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
236474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // make sure to clear all GL error flags
236574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    while ( glGetError() != GL_NO_ERROR ) ;
236674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
236774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // create a FBO
236874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    GLuint name, tname;
236974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glGenRenderbuffersOES(1, &tname);
237074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindRenderbufferOES(GL_RENDERBUFFER_OES, tname);
237174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA8_OES, sw, sh);
2372fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian
237374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glGenFramebuffersOES(1, &name);
237474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
237574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES,
237674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, tname);
237774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
237874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
2379c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
238074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    if (status == GL_FRAMEBUFFER_COMPLETE_OES) {
238174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
238274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // invert everything, b/c glReadPixel() below will invert the FB
238374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glViewport(0, 0, sw, sh);
238474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_PROJECTION);
238574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glPushMatrix();
238674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glLoadIdentity();
2387ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian        glOrthof(0, hw_w, hw_h, 0, 0, 1);
238874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_MODELVIEW);
238974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
239074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // redraw the screen entirely...
239174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glClearColor(0,0,0,1);
239274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
2393f653b897a449e10d6cbfb6e0812f7b0bb02d6482Mathias Agopian
23943ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian        const Vector< sp<LayerBase> >& layers(hw->getVisibleLayersSortedByZ());
23959575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        const size_t count = layers.size();
239674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        for (size_t i=0 ; i<count ; ++i) {
239774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            const sp<LayerBase>& layer(layers[i]);
23983ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian            const uint32_t z = layer->drawingState().z;
23993ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian            if (z >= minLayerZ && z <= maxLayerZ) {
24003ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian                if (filtering) layer->setFiltering(true);
24013ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian                layer->draw(hw);
24023ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian                if (filtering) layer->setFiltering(false);
2403bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian            }
240474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        }
240574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
240674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // check for errors and return screen capture
240774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        if (glGetError() != GL_NO_ERROR) {
240874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // error while rendering
240974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            result = INVALID_OPERATION;
241074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        } else {
241174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // allocate shared memory large enough to hold the
241274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // screen capture
241374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            sp<MemoryHeapBase> base(
241474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    new MemoryHeapBase(size, 0, "screen-capture") );
241574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            void* const ptr = base->getBase();
241674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            if (ptr) {
241774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                // capture the screen with glReadPixels()
2418fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian                ScopedTrace _t(ATRACE_TAG, "glReadPixels");
241974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                glReadPixels(0, 0, sw, sh, GL_RGBA, GL_UNSIGNED_BYTE, ptr);
242074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                if (glGetError() == GL_NO_ERROR) {
242174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *heap = base;
242274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *w = sw;
242374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *h = sh;
242474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *f = PIXEL_FORMAT_RGBA_8888;
242574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    result = NO_ERROR;
242674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                }
242774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            } else {
242874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                result = NO_MEMORY;
242974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            }
243074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        }
243174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glViewport(0, 0, hw_w, hw_h);
243274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_PROJECTION);
243374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glPopMatrix();
243474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_MODELVIEW);
243574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    } else {
243674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        result = BAD_VALUE;
243774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    }
243874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
243974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // release FBO resources
244074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
244174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glDeleteRenderbuffersOES(1, &tname);
244274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glDeleteFramebuffersOES(1, &name);
2443e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian
24444297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->compositionComplete();
2445e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian
2446ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian//    ALOGD("screenshot: result = %s", result<0 ? strerror(result) : "OK");
2447c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
244874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    return result;
244974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian}
245074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
245174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
24529d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brownstatus_t SurfaceFlinger::captureScreen(const sp<IBinder>& display,
24531b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        sp<IMemoryHeap>* heap,
245474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t* width, uint32_t* height, PixelFormat* format,
2455bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t sw, uint32_t sh,
2456bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ, uint32_t maxLayerZ)
24571b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian{
24589d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown    if (CC_UNLIKELY(display == 0))
24591b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        return BAD_VALUE;
24601b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
24611b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
24621b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        return INVALID_OPERATION;
24631b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
24641b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    class MessageCaptureScreen : public MessageBase {
24651b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        SurfaceFlinger* flinger;
24669d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown        sp<IBinder> display;
24671b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        sp<IMemoryHeap>* heap;
24681b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        uint32_t* w;
24691b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        uint32_t* h;
24701b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        PixelFormat* f;
247174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t sw;
247274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t sh;
2473bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ;
2474bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t maxLayerZ;
24751b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        status_t result;
24761b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    public:
24779d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown        MessageCaptureScreen(SurfaceFlinger* flinger, const sp<IBinder>& display,
247874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                sp<IMemoryHeap>* heap, uint32_t* w, uint32_t* h, PixelFormat* f,
2479bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                uint32_t sw, uint32_t sh,
2480bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                uint32_t minLayerZ, uint32_t maxLayerZ)
24819d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown            : flinger(flinger), display(display),
2482bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              heap(heap), w(w), h(h), f(f), sw(sw), sh(sh),
2483bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              minLayerZ(minLayerZ), maxLayerZ(maxLayerZ),
2484bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              result(PERMISSION_DENIED)
24851b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
24861b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
24871b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        status_t getResult() const {
24881b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            return result;
24891b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
24901b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        virtual bool handler() {
24911b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
24929d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown            result = flinger->captureScreenImplLocked(display,
2493bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                    heap, w, h, f, sw, sh, minLayerZ, maxLayerZ);
24941b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            return true;
24951b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
24961b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    };
24971b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
24981b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    sp<MessageBase> msg = new MessageCaptureScreen(this,
24999d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown            display, heap, width, height, format, sw, sh, minLayerZ, maxLayerZ);
25001b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    status_t res = postMessageSync(msg);
25011b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    if (res == NO_ERROR) {
25021b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        res = static_cast<MessageCaptureScreen*>( msg.get() )->getResult();
25031b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    }
25041b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    return res;
25051b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian}
25061b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
25071b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// ---------------------------------------------------------------------------
25081b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
2509921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::LayerVector::LayerVector() {
2510921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
2511921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
2512921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::LayerVector::LayerVector(const LayerVector& rhs)
2513921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    : SortedVector<sp<LayerBase> >(rhs) {
2514921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
2515921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
2516921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianint SurfaceFlinger::LayerVector::do_compare(const void* lhs,
2517921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    const void* rhs) const
2518edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2519be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    // sort layers per layer-stack, then by z-order and finally by sequence
2520921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    const sp<LayerBase>& l(*reinterpret_cast<const sp<LayerBase>*>(lhs));
2521921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    const sp<LayerBase>& r(*reinterpret_cast<const sp<LayerBase>*>(rhs));
2522be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian
2523be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    uint32_t ls = l->currentState().layerStack;
2524be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    uint32_t rs = r->currentState().layerStack;
2525be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    if (ls != rs)
2526be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian        return ls - rs;
2527be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian
2528921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    uint32_t lz = l->currentState().z;
2529921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    uint32_t rz = r->currentState().z;
2530be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    if (lz != rz)
2531be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian        return lz - rz;
2532be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian
2533be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    return l->sequence - r->sequence;
2534921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
2535921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
2536921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian// ---------------------------------------------------------------------------
2537921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
25383ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias AgopianSurfaceFlinger::DisplayDeviceState::DisplayDeviceState()
25393ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    : type(DisplayDevice::DISPLAY_ID_INVALID) {
2540e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
2541e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
25423ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias AgopianSurfaceFlinger::DisplayDeviceState::DisplayDeviceState(DisplayDevice::DisplayType type)
25433ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    : type(type), layerStack(0), orientation(0) {
2544da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian    viewport.makeInvalid();
2545da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian    frame.makeInvalid();
2546b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
25477303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
2548b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// ---------------------------------------------------------------------------
254996f0819f81293076e652792794a961543e6750d7Mathias Agopian
25509a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::GraphicBufferAlloc() {}
25519a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
25529a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::~GraphicBufferAlloc() {}
25539a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
25549a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h,
2555d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        PixelFormat format, uint32_t usage, status_t* error) {
25569a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(w, h, format, usage));
25579a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    status_t err = graphicBuffer->initCheck();
2558d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian    *error = err;
2559a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (err != 0 || graphicBuffer->handle == 0) {
2560d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        if (err == NO_MEMORY) {
2561d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian            GraphicBuffer::dumpAllocationsToSystemLog();
2562d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        }
2563e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE("GraphicBufferAlloc::createGraphicBuffer(w=%d, h=%d) "
2564a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian             "failed (%s), handle=%p",
2565a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                w, h, strerror(-err), graphicBuffer->handle);
25669a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis        return 0;
25679a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    }
25689a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    return graphicBuffer;
25699a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis}
25709a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
25719a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis// ---------------------------------------------------------------------------
25729a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
2573edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
2574