SurfaceFlinger.cpp revision cd60f99aba9e750700a967db30b74a29145739cf
1edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/*
2edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
3edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
4edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * you may not use this file except in compliance with the License.
6edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * You may obtain a copy of the License at
7edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
8edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
10edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * See the License for the specific language governing permissions and
14edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * limitations under the License.
15edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */
16edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
171c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#define ATRACE_TAG ATRACE_TAG_GRAPHICS
181c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
19edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdint.h>
20921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <sys/types.h>
21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <errno.h>
22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <math.h>
23921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
24921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <EGL/egl.h>
25921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <GLES/gl.h>
26edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
27edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/log.h>
28edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/properties.h>
29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
30c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IPCThreadState.h>
31c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IServiceManager.h>
327303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian#include <binder/MemoryHeapBase.h>
3399b49840d309727678b77403d6cc9f920111623fMathias Agopian#include <binder/PermissionCache.h>
347303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
35c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian#include <ui/DisplayInfo.h>
36c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian
37921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <gui/BitTube.h>
381a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <gui/BufferQueue.h>
391a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <gui/IDisplayEventConnection.h>
40921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <gui/SurfaceTextureClient.h>
41921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
42921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <ui/GraphicBufferAllocator.h>
43921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <ui/PixelFormat.h>
44d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String8.h>
46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String16.h>
47edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/StopWatch.h>
481c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#include <utils/Trace.h>
49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
50921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <private/android_filesystem_config.h>
51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h"
5390ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include "DdmConnection.h"
540f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian#include "DisplayDevice.h"
55db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian#include "Client.h"
56d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian#include "EventThread.h"
571f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian#include "GLExtensions.h"
58edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h"
59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerDim.h"
60118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian#include "LayerScreenshot.h"
61edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h"
62edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
63a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#include "DisplayHardware/FramebufferSurface.h"
64a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian#include "DisplayHardware/HWComposer.h"
65edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
66a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
67bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian#define EGL_VERSION_HW_ANDROID  0x3143
68bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DISPLAY_COUNT       1
70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
73edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
7499b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sHardwareTest("android.permission.HARDWARE_TEST");
7599b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER");
7699b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER");
7799b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sDump("android.permission.DUMP");
7899b49840d309727678b77403d6cc9f920111623fMathias Agopian
7999b49840d309727678b77403d6cc9f920111623fMathias Agopian// ---------------------------------------------------------------------------
8099b49840d309727678b77403d6cc9f920111623fMathias Agopian
81edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::SurfaceFlinger()
82edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    :   BnSurfaceComposer(), Thread(false),
83edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mTransactionFlags(0),
8428378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        mTransationPending(false),
85076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved(false),
8652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        mRepaintEverything(0),
87edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mBootTime(systemTime()),
88edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mVisibleRegionsDirty(false),
89a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        mHwWorkListDirty(false),
90edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDebugRegion(0),
918afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian        mDebugDDMS(0),
9273d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian        mDebugDisableHWC(0),
93a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian        mDebugDisableTransformHint(0),
949795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInSwapBuffers(0),
959795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastSwapBufferTime(0),
969795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInTransaction(0),
979795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastTransactionTime(0),
985f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        mBootFinished(false)
99edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
100a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI("SurfaceFlinger is starting");
101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // debugging stuff...
103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char value[PROPERTY_VALUE_MAX];
1048afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    property_get("debug.sf.showupdates", value, "0");
106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDebugRegion = atoi(value);
1078afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
1088afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    property_get("debug.sf.ddms", value, "0");
1098afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    mDebugDDMS = atoi(value);
1108afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    if (mDebugDDMS) {
1118afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian        DdmConnection::start(getServiceName());
1128afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    }
1138afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
114c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    ALOGI_IF(mDebugRegion, "showupdates enabled");
115c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    ALOGI_IF(mDebugDDMS, "DDMS debugging enabled");
116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
11899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::onFirstRef()
11999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
12099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.init(this);
12199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
12299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY);
12399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
12499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // Wait for the main thread to be done with its initialization
12599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mReadyToRunBarrier.wait();
12699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
12799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
12899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::~SurfaceFlinger()
130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
131a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
132a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
133a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglTerminate(display);
134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
13699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::binderDied(const wp<IBinder>& who)
13799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
13899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // the window manager died on us. prepare its eulogy.
13999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
14099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // reset screen orientation
14199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    Vector<ComposerState> state;
1428b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian    Vector<DisplayState> displays;
1438b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian    DisplayState d;
144818b46058aa3006e1d3c178abd36d4f10823f5d9Mathias Agopian    d.what = DisplayState::eOrientationChanged;
145ea599dfff03b45903dae3288274c31cb24fd483fJesse Hall    d.token = mDefaultDisplays[DisplayDevice::DISPLAY_ID_MAIN];
1463165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian    d.orientation = DisplayState::eOrientationDefault;
1478b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian    displays.add(d);
1488b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian    setTransactionState(state, displays, 0);
14999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
15099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // restart the boot-animation
151a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    startBootAnim();
15299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
15399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
1547e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopiansp<ISurfaceComposerClient> SurfaceFlinger::createConnection()
155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
15696f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<ISurfaceComposerClient> bclient;
15796f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<Client> client(new Client(this));
15896f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = client->initCheck();
15996f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR) {
16096f0819f81293076e652792794a961543e6750d7Mathias Agopian        bclient = client;
161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return bclient;
163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
165e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopiansp<IBinder> SurfaceFlinger::createDisplay()
166e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{
167e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    class DisplayToken : public BBinder {
168e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        sp<SurfaceFlinger> flinger;
169e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        virtual ~DisplayToken() {
170e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             // no more references, this display must be terminated
171e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             Mutex::Autolock _l(flinger->mStateLock);
172e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             flinger->mCurrentState.displays.removeItem(this);
173e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             flinger->setTransactionFlags(eDisplayTransactionNeeded);
174e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian         }
175e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian     public:
176e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        DisplayToken(const sp<SurfaceFlinger>& flinger)
177e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            : flinger(flinger) {
178e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
179e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    };
180e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
181e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    sp<BBinder> token = new DisplayToken(this);
182e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
183e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    Mutex::Autolock _l(mStateLock);
184e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    DisplayDeviceState info(intptr_t(token.get())); // FIXME: we shouldn't use the address for the id
185e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    mCurrentState.displays.add(token, info);
186e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
187e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return token;
188e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
189e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
190e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopiansp<IBinder> SurfaceFlinger::getBuiltInDisplay(int32_t id) {
191e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    if (uint32_t(id) >= DisplayDevice::DISPLAY_ID_COUNT) {
192e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        ALOGE("getDefaultDisplay: id=%d is not a valid default display id", id);
193e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        return NULL;
194e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
195e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return mDefaultDisplays[id];
196e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
197e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
1989a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc()
1999a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis{
2009a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc());
2019a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    return gba;
2029a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis}
203b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
204edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::bootFinished()
205edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
206edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t now = systemTime();
207edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t duration = now - mBootTime;
208a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
2093330b203039dea366d4981db1408a460134b2d2cMathias Agopian    mBootFinished = true;
2101f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
2111f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // wait patiently for the window manager death
2121f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    const String16 name("window");
2131f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    sp<IBinder> window(defaultServiceManager()->getService(name));
2141f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    if (window != 0) {
215921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        window->linkToDeath(static_cast<IBinder::DeathRecipient*>(this));
2161f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    }
2171f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
2181f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // stop boot animation
219a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // formerly we would just kill the process, but we now ask it to exit so it
220a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // can choose where to stop the animation.
221a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("service.bootanim.exit", "1");
222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
224921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianvoid SurfaceFlinger::deleteTextureAsync(GLuint texture) {
225921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    class MessageDestroyGLTexture : public MessageBase {
226921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        GLuint texture;
227921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    public:
228921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        MessageDestroyGLTexture(GLuint texture)
229921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian            : texture(texture) {
230921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        }
231921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        virtual bool handler() {
232921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian            glDeleteTextures(1, &texture);
233921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian            return true;
234921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        }
235921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    };
236921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    postMessageAsync(new MessageDestroyGLTexture(texture));
237921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
238921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
239a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianstatus_t SurfaceFlinger::selectConfigForPixelFormat(
240a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        EGLDisplay dpy,
241a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        EGLint const* attrs,
242a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        PixelFormat format,
243a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        EGLConfig* outConfig)
244a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian{
245a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLConfig config = NULL;
246a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLint numConfigs = -1, n=0;
247a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglGetConfigs(dpy, NULL, 0, &numConfigs);
248a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLConfig* const configs = new EGLConfig[numConfigs];
249a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglChooseConfig(dpy, attrs, configs, numConfigs, &n);
250a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    for (int i=0 ; i<n ; i++) {
251a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        EGLint nativeVisualId = 0;
252a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        eglGetConfigAttrib(dpy, configs[i], EGL_NATIVE_VISUAL_ID, &nativeVisualId);
253a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        if (nativeVisualId>0 && format == nativeVisualId) {
254a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            *outConfig = configs[i];
255a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            delete [] configs;
256a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            return NO_ERROR;
257a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        }
258a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    }
259a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    delete [] configs;
260a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    return NAME_NOT_FOUND;
261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
263a49126087b4494f4ef50873f3a3f6727265f6621Mathias AgopianEGLConfig SurfaceFlinger::selectEGLConfig(EGLDisplay display, EGLint nativeVisualId) {
264a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // select our EGLConfig. It must support EGL_RECORDABLE_ANDROID if
265a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // it is to be used with WIFI displays
266a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLConfig config;
267a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLint dummy;
268a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    status_t err;
269a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLint attribs[] = {
270a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            EGL_SURFACE_TYPE,           EGL_WINDOW_BIT,
271a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            EGL_RECORDABLE_ANDROID,     EGL_TRUE,
272a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            EGL_NONE
273a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    };
274a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    err = selectConfigForPixelFormat(display, attribs, nativeVisualId, &config);
275a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    if (err) {
276a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        // maybe we failed because of EGL_RECORDABLE_ANDROID
277a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        ALOGW("couldn't find an EGLConfig with EGL_RECORDABLE_ANDROID");
278a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        attribs[2] = EGL_NONE;
279a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        err = selectConfigForPixelFormat(display, attribs, nativeVisualId, &config);
280a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    }
281a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGE_IF(err, "couldn't find an EGLConfig matching the screen format");
282a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    if (eglGetConfigAttrib(display, config, EGL_CONFIG_CAVEAT, &dummy) == EGL_TRUE) {
283a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        ALOGW_IF(dummy == EGL_SLOW_CONFIG, "EGL_SLOW_CONFIG selected!");
284a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    }
285a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    return config;
286a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
287edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
288a49126087b4494f4ef50873f3a3f6727265f6621Mathias AgopianEGLContext SurfaceFlinger::createGLContext(EGLDisplay display, EGLConfig config) {
289a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // Also create our EGLContext
290a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLint contextAttributes[] = {
291a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#ifdef EGL_IMG_context_priority
292a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#ifdef HAS_CONTEXT_PRIORITY
293a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#warning "using EGL_IMG_context_priority"
294a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_HIGH_IMG,
295a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#endif
296a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#endif
297a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            EGL_NONE, EGL_NONE
298a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    };
299a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLContext ctxt = eglCreateContext(display, config, NULL, contextAttributes);
300a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGE_IF(ctxt==EGL_NO_CONTEXT, "EGLContext creation failed");
301a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    return ctxt;
302a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
304a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianvoid SurfaceFlinger::initializeGL(EGLDisplay display, EGLSurface surface) {
305a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLBoolean result = eglMakeCurrent(display, surface, surface, mEGLContext);
306a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    if (!result) {
307a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        ALOGE("Couldn't create a working GLES context. check logs. exiting...");
308a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        exit(0);
309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
310edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
311a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    GLExtensions& extensions(GLExtensions::getInstance());
312a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    extensions.initWithGLStrings(
313a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            glGetString(GL_VENDOR),
314a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            glGetString(GL_RENDERER),
315a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            glGetString(GL_VERSION),
316a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            glGetString(GL_EXTENSIONS),
317a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            eglQueryString(display, EGL_VENDOR),
318a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            eglQueryString(display, EGL_VERSION),
319a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            eglQueryString(display, EGL_EXTENSIONS));
3208b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
321a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLint w, h;
322a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglQuerySurface(display, surface, EGL_WIDTH,  &w);
323a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglQuerySurface(display, surface, EGL_HEIGHT, &h);
3248b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
325a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
326a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    glGetIntegerv(GL_MAX_VIEWPORT_DIMS, mMaxViewportDims);
3277303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
328edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
3298b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber    glPixelStorei(GL_PACK_ALIGNMENT, 4);
330edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glEnableClientState(GL_VERTEX_ARRAY);
331edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glShadeModel(GL_FLAT);
332edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_DITHER);
333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_CULL_FACE);
334edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
335a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    struct pack565 {
336a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        inline uint16_t operator() (int r, int g, int b) const {
337a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            return (r<<11)|(g<<5)|b;
338a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        }
339a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    } pack565;
340a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
3419575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    const uint16_t protTexData[] = { pack565(0x03, 0x03, 0x03) };
3429575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glGenTextures(1, &mProtectedTexName);
3439575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glBindTexture(GL_TEXTURE_2D, mProtectedTexName);
3449575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3459575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3469575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
3479575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
3489575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0,
3499575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis            GL_RGB, GL_UNSIGNED_SHORT_5_6_5, protTexData);
350edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
351edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glViewport(0, 0, w, h);
352edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glMatrixMode(GL_PROJECTION);
353edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glLoadIdentity();
354ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    // put the origin in the left-bottom corner
355ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    glOrthof(0, w, 0, h, 0, 1); // l=0, r=w ; b=0, t=h
356edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
357a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // print some debugging info
358a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLint r,g,b,a;
359a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglGetConfigAttrib(display, mEGLConfig, EGL_RED_SIZE,   &r);
360a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglGetConfigAttrib(display, mEGLConfig, EGL_GREEN_SIZE, &g);
361a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglGetConfigAttrib(display, mEGLConfig, EGL_BLUE_SIZE,  &b);
362a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglGetConfigAttrib(display, mEGLConfig, EGL_ALPHA_SIZE, &a);
363a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("EGL informations:");
364a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("vendor    : %s", extensions.getEglVendor());
365a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("version   : %s", extensions.getEglVersion());
366a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("extensions: %s", extensions.getEglExtension());
367a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("Client API: %s", eglQueryString(display, EGL_CLIENT_APIS)?:"Not Supported");
368a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("EGLSurface: %d-%d-%d-%d, config=%p", r, g, b, a, mEGLConfig);
369a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("OpenGL ES informations:");
370a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("vendor    : %s", extensions.getVendor());
371a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("renderer  : %s", extensions.getRenderer());
372a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("version   : %s", extensions.getVersion());
373a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("extensions: %s", extensions.getExtension());
374a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("GL_MAX_TEXTURE_SIZE = %d", mMaxTextureSize);
375a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("GL_MAX_VIEWPORT_DIMS = %d x %d", mMaxViewportDims[0], mMaxViewportDims[1]);
376a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
377a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
378a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianstatus_t SurfaceFlinger::readyToRun()
379a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian{
380a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI(  "SurfaceFlinger's main thread ready to run. "
381a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            "Initializing graphics H/W...");
382a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
383a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // initialize EGL
38434a09ba1efd706323a15633da5044b352988eb5fJesse Hall    mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
38534a09ba1efd706323a15633da5044b352988eb5fJesse Hall    eglInitialize(mEGLDisplay, NULL, NULL);
386a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
387a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // Initialize the main display
388a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // create native window to main display
3891a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    sp<FramebufferSurface> fbs = FramebufferSurface::create();
3901a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    if (fbs == NULL) {
391a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        ALOGE("Display subsystem failed to initialize. check logs. exiting...");
392a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        exit(0);
393a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    }
394a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
395e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    sp<SurfaceTextureClient> stc(new SurfaceTextureClient(
396e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            static_cast<sp<ISurfaceTexture> >(fbs->getBufferQueue())));
3971a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
398a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // initialize the config and context
399a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    int format;
4001a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    ANativeWindow* const anw = stc.get();
4011a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    anw->query(anw, NATIVE_WINDOW_FORMAT, &format);
40234a09ba1efd706323a15633da5044b352988eb5fJesse Hall    mEGLConfig  = selectEGLConfig(mEGLDisplay, format);
40334a09ba1efd706323a15633da5044b352988eb5fJesse Hall    mEGLContext = createGLContext(mEGLDisplay, mEGLConfig);
404a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
405a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // initialize our main display hardware
406e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
407e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    for (size_t i=0 ; i<DisplayDevice::DISPLAY_ID_COUNT ; i++) {
408e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        mDefaultDisplays[i] = new BBinder();
409e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        mCurrentState.displays.add(mDefaultDisplays[i], DisplayDeviceState(i));
410e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
411e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    sp<DisplayDevice> hw = new DisplayDevice(this,
412e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            DisplayDevice::DISPLAY_ID_MAIN, anw, fbs, mEGLConfig);
413e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    mDisplays.add(hw->getDisplayId(), hw);
414a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
415a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    //  initialize OpenGL ES
4164297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    EGLSurface surface = hw->getEGLSurface();
41734a09ba1efd706323a15633da5044b352988eb5fJesse Hall    initializeGL(mEGLDisplay, surface);
418d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
419028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian    // start the EventThread
420028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian    mEventThread = new EventThread(this);
421028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian    mEventQueue.setEventThread(mEventThread);
422028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian
4238630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    // initialize the H/W composer
4248b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    mHwc = new HWComposer(this,
4258b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            *static_cast<HWComposer::EventHandler *>(this),
4268b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            fbs->getFbHal());
42792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian
42892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    // initialize our drawing state
42992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    mDrawingState = mCurrentState;
4308630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
431a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // We're now ready to accept clients...
432d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian    mReadyToRunBarrier.open();
433d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
434a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    // start boot animation
435a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    startBootAnim();
4368b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
437edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
438edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
439edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
440a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopianvoid SurfaceFlinger::startBootAnim() {
441a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // start boot animation
442a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("service.bootanim.exit", "0");
443a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("ctl.start", "bootanim");
444a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian}
445a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian
446a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianuint32_t SurfaceFlinger::getMaxTextureSize() const {
447a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    return mMaxTextureSize;
448a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
449a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
450a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianuint32_t SurfaceFlinger::getMaxViewportDims() const {
451a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    return mMaxViewportDims[0] < mMaxViewportDims[1] ?
452a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            mMaxViewportDims[0] : mMaxViewportDims[1];
453a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
454a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
455edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
456d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
457582270d69db94286a248bd829f1ae6f910d45124Jamie Gennisbool SurfaceFlinger::authenticateSurfaceTexture(
458582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis        const sp<ISurfaceTexture>& surfaceTexture) const {
459134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    Mutex::Autolock _l(mStateLock);
460582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis    sp<IBinder> surfaceTextureBinder(surfaceTexture->asBinder());
461134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
462134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // Check the visible layer list for the ISurface
463134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
464134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    size_t count = currentLayers.size();
465134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    for (size_t i=0 ; i<count ; i++) {
466134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        const sp<LayerBase>& layer(currentLayers[i]);
467134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        sp<LayerBaseClient> lbc(layer->getLayerBaseClient());
468582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis        if (lbc != NULL) {
469582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder();
470582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            if (lbcBinder == surfaceTextureBinder) {
471582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis                return true;
472582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            }
473134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        }
474134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    }
475134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
476134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // Check the layers in the purgatory.  This check is here so that if a
477582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis    // SurfaceTexture gets destroyed before all the clients are done using it,
478582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis    // the error will not be reported as "surface XYZ is not authenticated", but
479134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // will instead fail later on when the client tries to use the surface,
480134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // which should be reported as "surface XYZ returned an -ENODEV".  The
481134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // purgatorized layers are no less authentic than the visible ones, so this
482134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // should not cause any harm.
483134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    size_t purgatorySize =  mLayerPurgatory.size();
484134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    for (size_t i=0 ; i<purgatorySize ; i++) {
485134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
486134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        sp<LayerBaseClient> lbc(layer->getLayerBaseClient());
487582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis        if (lbc != NULL) {
488582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder();
489582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            if (lbcBinder == surfaceTextureBinder) {
490582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis                return true;
491582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            }
492134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        }
493134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    }
494134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
495134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    return false;
496134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis}
497134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
498c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopianstatus_t SurfaceFlinger::getDisplayInfo(DisplayID dpy, DisplayInfo* info) {
4991e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian    // TODO: this is here only for compatibility -- should go away eventually.
5001e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian    if (uint32_t(dpy) >= 1) {
501c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian        return BAD_INDEX;
502c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian    }
5038b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian
5048b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    const HWComposer& hwc(getHwComposer());
5058b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    float xdpi = hwc.getDpiX();
5068b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    float ydpi = hwc.getDpiY();
5078b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian
5088b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    // TODO: Not sure if display density should handled by SF any longer
5098b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    class Density {
5108b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        static int getDensityFromProperty(char const* propName) {
5118b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            char property[PROPERTY_VALUE_MAX];
5128b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            int density = 0;
5138b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            if (property_get(propName, property, NULL) > 0) {
5148b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian                density = atoi(property);
5158b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            }
5168b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            return density;
5178b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        }
5188b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    public:
5198b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        static int getEmuDensity() {
5208b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            return getDensityFromProperty("qemu.sf.lcd_density"); }
5218b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        static int getBuildDensity()  {
5228b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            return getDensityFromProperty("ro.sf.lcd_density"); }
5238b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    };
5248b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    // The density of the device is provided by a build property
5258b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    float density = Density::getBuildDensity() / 160.0f;
5268b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    if (density == 0) {
5278b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        // the build doesn't provide a density -- this is wrong!
5288b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        // use xdpi instead
5298b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        ALOGE("ro.sf.lcd_density must be defined as a build property");
5308b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        density = xdpi / 160.0f;
5318b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    }
5328b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    if (Density::getEmuDensity()) {
5338b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        // if "qemu.sf.lcd_density" is specified, it overrides everything
5348b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        xdpi = ydpi = density = Density::getEmuDensity();
5358b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        density /= 160.0f;
5368b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    }
5378b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian
5384297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    sp<const DisplayDevice> hw(getDefaultDisplayDevice());
5394297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    info->w = hw->getWidth();
5404297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    info->h = hw->getHeight();
5418b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    info->xdpi = xdpi;
5428b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    info->ydpi = ydpi;
5438b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    info->fps = float(1e9 / hwc.getRefreshPeriod());
5448b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    info->density = density;
5454297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    info->orientation = hw->getOrientation();
546888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian    // TODO: this needs to go away (currently needed only by webkit)
5474297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    getPixelFormatInfo(hw->getFormat(), &info->pixelFormatInfo);
548888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian    return NO_ERROR;
549c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian}
550c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian
551d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian// ----------------------------------------------------------------------------
552d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
553d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopiansp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection() {
5548aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian    return mEventThread->createEventConnection();
555bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian}
556bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
5575f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopianvoid SurfaceFlinger::connectDisplay(const sp<ISurfaceTexture> surface) {
5583094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
5595f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    sp<IBinder> token;
5603094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    { // scope for the lock
5613094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        Mutex::Autolock _l(mStateLock);
5625f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        token = mExtDisplayToken;
5633094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    }
5643094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
5655f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    if (token == 0) {
5665f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        token = createDisplay();
5673094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    }
5683094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
5695f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    { // scope for the lock
5705f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        Mutex::Autolock _l(mStateLock);
5715f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        if (surface == 0) {
5725f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian            // release our current display. we're guarantee to have
5735f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian            // a reference to it (token), while we hold the lock
5745f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian            mExtDisplayToken = 0;
5755f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        } else {
5765f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian            mExtDisplayToken = token;
5775f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        }
5785f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian
5795f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        DisplayDeviceState& info(mCurrentState.displays.editValueFor(token));
5805f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        info.surface = surface;
5815f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        setTransactionFlags(eDisplayTransactionNeeded);
5825f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    }
5833094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian}
5843094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
585edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
58699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
58799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::waitForEvent() {
58899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.waitMessage();
58999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
59099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
59199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalTransaction() {
59299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.invalidate();
59399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
59499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
59599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalLayerUpdate() {
59699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.invalidate();
59799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
59899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
59999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalRefresh() {
60099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.refresh();
60199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
60299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
60399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg,
60499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        nsecs_t reltime, uint32_t flags) {
60599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return mEventQueue.postMessage(msg, reltime);
60699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
60799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
60899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,
60999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        nsecs_t reltime, uint32_t flags) {
61099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    status_t res = mEventQueue.postMessage(msg, reltime);
61199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    if (res == NO_ERROR) {
61299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        msg->wait();
61399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    }
61499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return res;
61599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
616edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
6174fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianbool SurfaceFlinger::threadLoop() {
618edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    waitForEvent();
61999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return true;
62099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
621edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
6228630320433bd15aca239522e54e711ef6372ab07Mathias Agopianvoid SurfaceFlinger::onVSyncReceived(int dpy, nsecs_t timestamp) {
6238630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    mEventThread->onVSyncReceived(dpy, timestamp);
6248630320433bd15aca239522e54e711ef6372ab07Mathias Agopian}
6258630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
6268630320433bd15aca239522e54e711ef6372ab07Mathias Agopianvoid SurfaceFlinger::eventControl(int event, int enabled) {
6278630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    getHwComposer().eventControl(event, enabled);
6288630320433bd15aca239522e54e711ef6372ab07Mathias Agopian}
6298630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
6304fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::onMessageReceived(int32_t what) {
6311c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
63299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    switch (what) {
6334fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    case MessageQueue::INVALIDATE:
6344fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        handleMessageTransaction();
6354fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        handleMessageInvalidate();
6364fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        signalRefresh();
6374fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        break;
6384fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    case MessageQueue::REFRESH:
6394fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        handleMessageRefresh();
6404fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        break;
6414fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
6424fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
643edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
6444fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageTransaction() {
645e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    uint32_t transactionFlags = peekTransactionFlags(eTransactionMask);
6464fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    if (transactionFlags) {
64787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        handleTransaction(transactionFlags);
6484fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
6494fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
650edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
6514fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageInvalidate() {
652cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    ATRACE_CALL();
65387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    handlePageFlip();
6544fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
6553a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian
6564fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageRefresh() {
657cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    ATRACE_CALL();
658cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    preComposition();
659cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    rebuildLayerStacks();
660cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    setUpHWComposer();
661cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    doDebugFlashRegions();
662cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    doComposition();
663cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    postComposition();
664cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
665cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
666cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doDebugFlashRegions()
667cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{
668cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    // is debugging enabled
669cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (CC_LIKELY(!mDebugRegion))
670cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        return;
671cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
672cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    const bool repaintEverything = mRepaintEverything;
673cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
674cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
675cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        if (hw->canDraw()) {
676cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            // transform the dirty region into this screen's coordinate space
677cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            const Region dirtyRegion(hw->getDirtyRegion(repaintEverything));
678cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            if (!dirtyRegion.isEmpty()) {
679cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                // redraw the whole screen
680cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                doComposeSurfaces(hw, Region(hw->bounds()));
681cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
682cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                // and draw the dirty region
683cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                glDisable(GL_TEXTURE_EXTERNAL_OES);
684cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                glDisable(GL_TEXTURE_2D);
685cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                glDisable(GL_BLEND);
686cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                glColor4f(1, 0, 1, 1);
687cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                const int32_t height = hw->getHeight();
688cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                Region::const_iterator it = dirtyRegion.begin();
689cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                Region::const_iterator const end = dirtyRegion.end();
690cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                while (it != end) {
691cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                    const Rect& r = *it++;
692cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                    GLfloat vertices[][2] = {
693cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            { r.left,  height - r.top },
694cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            { r.left,  height - r.bottom },
695cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            { r.right, height - r.bottom },
696cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            { r.right, height - r.top }
697cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                    };
698cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                    glVertexPointer(2, GL_FLOAT, 0, vertices);
699cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
700cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                }
701cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                hw->compositionComplete();
702cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                // FIXME
703cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                if (hw->getDisplayId() >= DisplayDevice::DISPLAY_ID_COUNT) {
704cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                    eglSwapBuffers(mEGLDisplay, hw->getEGLSurface());
705cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                }
706cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            }
707cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        }
708cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
709cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
710cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    postFramebuffer();
711cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
712cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (mDebugRegion > 1) {
713cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        usleep(mDebugRegion * 1000);
714cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
715cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
716cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
717cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::preComposition()
718cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{
719cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    bool needExtraInvalidate = false;
720cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
721cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    const size_t count = currentLayers.size();
722cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    for (size_t i=0 ; i<count ; i++) {
723cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        if (currentLayers[i]->onPreComposition()) {
724cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            needExtraInvalidate = true;
725cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        }
726cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
727cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (needExtraInvalidate) {
728cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        signalLayerUpdate();
729cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
730cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
731a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
732cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::postComposition()
733cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{
734cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
735cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    const size_t count = currentLayers.size();
736cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    for (size_t i=0 ; i<count ; i++) {
737cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        currentLayers[i]->onPostComposition();
738cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
739cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
740cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
741cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::rebuildLayerStacks() {
742cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    // rebuild the visible layer list per screen
74352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    if (CC_UNLIKELY(mVisibleRegionsDirty)) {
744cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        ATRACE_CALL();
74587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        mVisibleRegionsDirty = false;
74687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        invalidateHwcGeometry();
74787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
74892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
7494297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            const sp<DisplayDevice>& hw(mDisplays[dpy]);
75087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            Region opaqueRegion;
75187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            Region dirtyRegion;
75287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            computeVisibleRegions(currentLayers,
7534297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                    hw->getLayerStack(), dirtyRegion, opaqueRegion);
7544297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->dirtyRegion.orSelf(dirtyRegion);
75587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
75687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            Vector< sp<LayerBase> > layersSortedByZ;
75787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            const size_t count = currentLayers.size();
75887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            for (size_t i=0 ; i<count ; i++) {
75987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian                const Layer::State& s(currentLayers[i]->drawingState());
7604297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                if (s.layerStack == hw->getLayerStack()) {
76187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian                    if (!currentLayers[i]->visibleRegion.isEmpty()) {
76287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian                        layersSortedByZ.add(currentLayers[i]);
76387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian                    }
76487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian                }
7653b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian            }
7664297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->setVisibleLayersSortedByZ(layersSortedByZ);
7674297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->undefinedRegion.set(hw->getBounds());
768cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            hw->undefinedRegion.subtractSelf(
769cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                    hw->getTransform().transform(opaqueRegion));
7703b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        }
7713b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
772cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
7733b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
774cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::setUpHWComposer() {
77552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    HWComposer& hwc(getHwComposer());
77652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    if (hwc.initCheck() == NO_ERROR) {
77752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        // build the h/w work list
77852bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        const bool workListsDirty = mHwWorkListDirty;
77952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        mHwWorkListDirty = false;
78092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
7814297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            sp<const DisplayDevice> hw(mDisplays[dpy]);
782cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            const Vector< sp<LayerBase> >& currentLayers(
783cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                    hw->getVisibleLayersSortedByZ());
78452bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            const size_t count = currentLayers.size();
785303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian
7861e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian            const int32_t id = hw->getDisplayId();
7871e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian            if (hwc.createWorkList(id, count) >= 0) {
7881e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                HWComposer::LayerListIterator cur = hwc.begin(id);
7891e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                const HWComposer::LayerListIterator end = hwc.end(id);
7901e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
7911e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                    const sp<LayerBase>& layer(currentLayers[i]);
7921e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian
7931e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                    if (CC_UNLIKELY(workListsDirty)) {
7941e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                        layer->setGeometry(hw, *cur);
7951e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                        if (mDebugDisableHWC || mDebugRegion) {
7961e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                            cur->setSkip(true);
7971e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                        }
79852bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian                    }
79952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian
8001e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                    /*
8011e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                     * update the per-frame h/w composer data for each layer
8021e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                     * and build the transparent region of the FB
8031e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                     */
8041e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                    layer->setPerFrameData(hw, *cur);
8051e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                }
80652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            }
80787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        }
80852bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        status_t err = hwc.prepare();
80952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
81052bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    }
811cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
81252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian
813cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doComposition() {
814cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    ATRACE_CALL();
81552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    const bool repaintEverything = android_atomic_and(0, &mRepaintEverything);
81692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
8174297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
818cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        if (hw->canDraw()) {
819cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            // transform the dirty region into this screen's coordinate space
820cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            const Region dirtyRegion(hw->getDirtyRegion(repaintEverything));
821cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            if (!dirtyRegion.isEmpty()) {
82252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian                // repaint the framebuffer (if needed)
823cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                doDisplayComposition(hw, dirtyRegion);
82452bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            }
825cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            hw->dirtyRegion.clear();
826cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            hw->flip(hw->swapRegion);
827cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            hw->swapRegion.clear();
82887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        }
82952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        // inform the h/w that we're done compositing
8304297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        hw->compositionComplete();
8314fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
83252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    postFramebuffer();
833edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
834edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
835edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer()
836edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
837841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
838b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian
839a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    const nsecs_t now = systemTime();
840a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = now;
841c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall
84252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    HWComposer& hwc(getHwComposer());
843ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall    if (hwc.initCheck() == NO_ERROR) {
84452bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        // FIXME: eventually commit() won't take arguments
8455f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        // FIXME: EGL spec says:
8465f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        //   "surface must be bound to the calling thread's current context,
8475f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        //    for the current rendering API."
848cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        DisplayDevice::makeCurrent(
849cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                getDisplayDevice(DisplayDevice::DISPLAY_ID_MAIN), mEGLContext);
8504297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        hwc.commit(mEGLDisplay, getDefaultDisplayDevice()->getEGLSurface());
85152bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    }
85252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian
85392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
8544297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        sp<const DisplayDevice> hw(mDisplays[dpy]);
8554297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const Vector< sp<LayerBase> >& currentLayers(hw->getVisibleLayersSortedByZ());
85652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        const size_t count = currentLayers.size();
85752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        if (hwc.initCheck() == NO_ERROR) {
8581e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian            int32_t id = hw->getDisplayId();
8591e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian            HWComposer::LayerListIterator cur = hwc.begin(id);
8601e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian            const HWComposer::LayerListIterator end = hwc.end(id);
86152bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            for (size_t i = 0; cur != end && i < count; ++i, ++cur) {
862d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian                currentLayers[i]->onLayerDisplayed(hw, &*cur);
86352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            }
864cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        } else {
86552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            for (size_t i = 0; i < count; i++) {
866d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian                currentLayers[i]->onLayerDisplayed(hw, NULL);
86752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            }
868ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall        }
869e8696a40e09b24b634214684d18526187b316a2fJamie Gennis    }
870e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
871a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mLastSwapBufferTime = systemTime() - now;
872a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = 0;
873edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
874edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
87587baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
876edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
877841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
878841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
879ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    Mutex::Autolock _l(mStateLock);
880ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    const nsecs_t now = systemTime();
881ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = now;
882ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
883ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // Here we're guaranteed that some transaction flags are set
884ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // so we can call handleTransactionLocked() unconditionally.
885ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // We call getTransactionFlags(), which will also clear the flags,
886ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // with mStateLock held to guarantee that mCurrentState won't change
887ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // until the transaction is committed.
888ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
889e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    transactionFlags = getTransactionFlags(eTransactionMask);
89087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    handleTransactionLocked(transactionFlags);
891ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
892ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mLastTransactionTime = systemTime() - now;
893ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = 0;
894ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    invalidateHwcGeometry();
895ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // here the transaction has been committed
8963d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian}
897edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
89887baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
8993d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{
9003d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    const LayerVector& currentLayers(mCurrentState.layersSortedByZ);
901edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t count = currentLayers.size();
902edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
903edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
904edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Traversal of the children
905edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * (perform the transaction for each of them if needed)
906edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
907edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
9083559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    if (transactionFlags & eTraversalNeeded) {
909edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (size_t i=0 ; i<count ; i++) {
910076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            const sp<LayerBase>& layer = currentLayers[i];
911edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
912edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (!trFlags) continue;
913edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
914edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const uint32_t flags = layer->doTransaction(0);
915edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (flags & Layer::eVisibleRegion)
916edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mVisibleRegionsDirty = true;
917edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
918edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
919edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
920edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
9213559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian     * Perform display own transactions if needed
922edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
923edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
924e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    if (transactionFlags & eDisplayTransactionNeeded) {
92592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        // here we take advantage of Vector's copy-on-write semantics to
92692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        // improve performance by skipping the transaction entirely when
92792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        // know that the lists are identical
928e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const KeyedVector<  wp<IBinder>, DisplayDeviceState>& curr(mCurrentState.displays);
929e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const KeyedVector<  wp<IBinder>, DisplayDeviceState>& draw(mDrawingState.displays);
93092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        if (!curr.isIdenticalTo(draw)) {
931edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
93292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            const size_t cc = curr.size();
93392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            const size_t dc = draw.size();
93492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian
93592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // find the displays that were removed
93692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // (ie: in drawing state but not in current state)
93792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // also handle displays that changed
93892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // (ie: displays that are in both lists)
93992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            for (size_t i=0 ; i<dc ; i++) {
940e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                const ssize_t j = curr.indexOfKey(draw.keyAt(i));
941e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                if (j < 0) {
94292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    // in drawing state but not in current state
94392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    if (draw[i].id != DisplayDevice::DISPLAY_ID_MAIN) {
94492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                        mDisplays.removeItem(draw[i].id);
94592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    } else {
94692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                        ALOGW("trying to remove the main display");
94792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    }
94892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                } else {
94992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    // this display is in both lists. see if something changed.
950e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                    const DisplayDeviceState& state(curr[j]);
951111b2d89221722d38f5b5b3ba65904ec22421839Mathias Agopian                    if (state.surface->asBinder() != draw[i].surface->asBinder()) {
952e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        // changing the surface is like destroying and
953e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        // recreating the DisplayDevice
954e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
955e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        sp<SurfaceTextureClient> stc(
956e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                                new SurfaceTextureClient(state.surface));
957e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
958e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        sp<DisplayDevice> disp = new DisplayDevice(this,
959e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                                state.id, stc, 0, mEGLConfig);
960e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
961e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        disp->setLayerStack(state.layerStack);
962e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        disp->setOrientation(state.orientation);
963e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        // TODO: take viewport and frame into account
964e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        mDisplays.replaceValueFor(state.id, disp);
965e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                    }
96692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    if (state.layerStack != draw[i].layerStack) {
9674297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                        const sp<DisplayDevice>& disp(getDisplayDevice(state.id));
96828947d7fbf9f486539322e8e12dd057568e180c2Mathias Agopian                        disp->setLayerStack(state.layerStack);
96992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    }
970e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                    if (state.orientation != draw[i].orientation ||
971e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        state.viewport != draw[i].viewport ||
972e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        state.frame != draw[i].frame) {
9734297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                        const sp<DisplayDevice>& disp(getDisplayDevice(state.id));
9744297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                        disp->setOrientation(state.orientation);
975e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        // TODO: take viewport and frame into account
97692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    }
97792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                }
97892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            }
97992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian
98092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // find displays that were added
98192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // (ie: in current state but not in drawing state)
98292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            for (size_t i=0 ; i<cc ; i++) {
983e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                if (draw.indexOfKey(curr.keyAt(i)) < 0) {
984e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                    const DisplayDeviceState& state(curr[i]);
985e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                    sp<SurfaceTextureClient> stc(
986e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                            new SurfaceTextureClient(state.surface));
987e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                    sp<DisplayDevice> disp = new DisplayDevice(this, state.id,
988e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                            stc, 0, mEGLConfig);
989e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                    mDisplays.add(state.id, disp);
99092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                }
99192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            }
992edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
9933559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    }
994edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
9953559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    /*
9963559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian     * Perform our own transaction if needed
9973559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian     */
998edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
999cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    const LayerVector& previousLayers(mDrawingState.layersSortedByZ);
1000cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (currentLayers.size() > previousLayers.size()) {
10013559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        // layers have been added
10023559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        mVisibleRegionsDirty = true;
10033559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    }
10043559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian
10053559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    // some layers might have been removed, so
10063559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    // we need to update the regions they're exposing.
10073559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    if (mLayersRemoved) {
10083559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        mLayersRemoved = false;
10093559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        mVisibleRegionsDirty = true;
10103559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        const size_t count = previousLayers.size();
10113559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        for (size_t i=0 ; i<count ; i++) {
10123559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian            const sp<LayerBase>& layer(previousLayers[i]);
10133559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian            if (currentLayers.indexOf(layer) < 0) {
10143559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                // this layer is not visible anymore
10153559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                // TODO: we could traverse the tree from front to back and
10163559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                //       compute the actual visible region
10173559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                // TODO: we could cache the transformed region
10183559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                Layer::State front(layer->drawingState());
10193559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                Region visibleReg = front.transform.transform(
10203559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                        Region(Rect(front.active.w, front.active.h)));
10213559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                invalidateLayerStack(front.layerStack, visibleReg);
10220aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            }
1023edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1024edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1025edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1026edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    commitTransaction();
10274fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
10284fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
10294fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::commitTransaction()
10304fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian{
10314fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    if (!mLayersPendingRemoval.isEmpty()) {
10324fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // Notify removed layers now that they can't be drawn from
10334fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        for (size_t i = 0; i < mLayersPendingRemoval.size(); i++) {
10344fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            mLayersPendingRemoval[i]->onRemoved();
10354fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        }
10364fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        mLayersPendingRemoval.clear();
10374fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
10384fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
10394fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mDrawingState = mCurrentState;
10404fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mTransationPending = false;
10414fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mTransactionCV.broadcast();
1042edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1043edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1044edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::computeVisibleRegions(
104587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const LayerVector& currentLayers, uint32_t layerStack,
104687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        Region& outDirtyRegion, Region& outOpaqueRegion)
1047edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1048841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
1049841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
1050edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveOpaqueLayers;
1051edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveCoveredLayers;
1052edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region dirty;
1053edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
105487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    outDirtyRegion.clear();
1055edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1056edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t i = currentLayers.size();
1057edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    while (i--) {
1058076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        const sp<LayerBase>& layer = currentLayers[i];
1059edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1060edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // start with the whole surface at its current location
1061970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian        const Layer::State& s(layer->drawingState());
1062edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
106387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        // only consider the layers on the given later stack
106487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        if (s.layerStack != layerStack)
106587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            continue;
106687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
1067ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
1068ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * opaqueRegion: area of a surface that is fully opaque.
1069ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
1070edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region opaqueRegion;
1071ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1072ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
1073ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visibleRegion: area of a surface that is visible on screen
1074ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * and not fully transparent. This is essentially the layer's
1075ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * footprint minus the opaque regions above it.
1076ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * Areas covered by a translucent surface are considered visible.
1077ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
1078edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region visibleRegion;
1079ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1080ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
1081ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * coveredRegion: area of a surface that is covered by all
1082ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visible regions above it (which includes the translucent areas).
1083ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
1084edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region coveredRegion;
1085ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1086ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1087ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // handle hidden surfaces by setting the visible region to empty
10883165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        if (CC_LIKELY(!(s.flags & layer_state_t::eLayerHidden) && s.alpha)) {
1089a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            const bool translucent = !layer->isOpaque();
10904fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            Rect bounds(layer->computeBounds());
1091edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            visibleRegion.set(bounds);
1092ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            if (!visibleRegion.isEmpty()) {
1093ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // Remove the transparent area from the visible region
1094ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (translucent) {
10954fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    Region transparentRegionScreen;
10964fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    const Transform tr(s.transform);
10974fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    if (tr.transformed()) {
10984fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                        if (tr.preserveRects()) {
10994fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            // transform the transparent region
11004fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            transparentRegionScreen = tr.transform(s.transparentRegion);
11014fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                        } else {
11024fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            // transformation too complex, can't do the
11034fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            // transparent region optimization.
11044fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            transparentRegionScreen.clear();
11054fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                        }
11064fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    } else {
11074fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                        transparentRegionScreen = s.transparentRegion;
11084fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    }
11094fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    visibleRegion.subtractSelf(transparentRegionScreen);
1110ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
1111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1112ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // compute the opaque region
11134fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                const int32_t layerOrientation = s.transform.getOrientation();
1114ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (s.alpha==255 && !translucent &&
1115ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                        ((layerOrientation & Transform::ROT_INVALID) == false)) {
1116ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    // the opaque region is the layer's footprint
1117ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    opaqueRegion = visibleRegion;
1118ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
1119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1122ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Clip the covered region to the visible region
1123ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        coveredRegion = aboveCoveredLayers.intersect(visibleRegion);
1124ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1125ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveCoveredLayers for next (lower) layer
1126ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        aboveCoveredLayers.orSelf(visibleRegion);
1127ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // subtract the opaque region covered by the layers above us
1129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        visibleRegion.subtractSelf(aboveOpaqueLayers);
1130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // compute this layer's dirty region
1132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (layer->contentDirty) {
1133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // we need to invalidate the whole region
1134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dirty = visibleRegion;
1135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // as well, as the old visible region
11364fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            dirty.orSelf(layer->visibleRegion);
1137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->contentDirty = false;
1138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
1139a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian            /* compute the exposed region:
1140ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   the exposed region consists of two components:
1141ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   1) what's VISIBLE now and was COVERED before
1142ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   2) what's EXPOSED now less what was EXPOSED before
1143ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
1144ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * note that (1) is conservative, we start with the whole
1145ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * visible region but only keep what used to be covered by
1146ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * something -- which mean it may have been exposed.
1147ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
1148ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * (2) handles areas that were not covered by anything but got
1149ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * exposed because of a resize.
1150a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian             */
1151ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region newExposed = visibleRegion - coveredRegion;
11524fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region oldVisibleRegion = layer->visibleRegion;
11534fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region oldCoveredRegion = layer->coveredRegion;
1154ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldExposed = oldVisibleRegion - oldCoveredRegion;
1155ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed);
1156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirty.subtractSelf(aboveOpaqueLayers);
1158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // accumulate to the screen dirty region
116087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        outDirtyRegion.orSelf(dirty);
1161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1162ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveOpaqueLayers for next (lower) layer
1163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        aboveOpaqueLayers.orSelf(opaqueRegion);
11648b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
1165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // Store the visible region is screen space
1166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setVisibleRegion(visibleRegion);
1167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setCoveredRegion(coveredRegion);
1168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
117087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    outOpaqueRegion = aboveOpaqueLayers;
1171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
117387baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::invalidateLayerStack(uint32_t layerStack,
117487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const Region& dirty) {
117592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
11764297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
11774297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        if (hw->getLayerStack() == layerStack) {
11784297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->dirtyRegion.orSelf(dirty);
117992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        }
118092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    }
118187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian}
118287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
118387baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handlePageFlip()
1184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
11854fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    Region dirtyRegion;
118699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
11874fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    bool visibleRegions = false;
1188cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
11894fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    const size_t count = currentLayers.size();
11904fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    for (size_t i=0 ; i<count ; i++) {
1191cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
119287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const Region dirty(layer->latchBuffer(visibleRegions));
119387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        Layer::State s(layer->drawingState());
119487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        invalidateLayerStack(s.layerStack, dirty);
11954fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
11964da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
11973b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    mVisibleRegionsDirty |= visibleRegions;
1198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1199edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1200ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopianvoid SurfaceFlinger::invalidateHwcGeometry()
1201ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian{
1202ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian    mHwWorkListDirty = true;
1203ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian}
1204ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian
120599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
1206cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doDisplayComposition(const sp<const DisplayDevice>& hw,
120787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const Region& inDirtyRegion)
1208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
120987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    Region dirtyRegion(inDirtyRegion);
121087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
1211b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // compute the invalid region
12124297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->swapRegion.orSelf(dirtyRegion);
1213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
12144297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    uint32_t flags = hw->getFlags();
12150f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian    if (flags & DisplayDevice::SWAP_RECTANGLE) {
121629d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // we can redraw only what's dirty, but since SWAP_RECTANGLE only
121729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // takes a rectangle, we must make sure to update that whole
121829d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // rectangle in that case
12194297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        dirtyRegion.set(hw->swapRegion.bounds());
1220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
12210f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian        if (flags & DisplayDevice::PARTIAL_UPDATES) {
122229d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // We need to redraw the rectangle that will be updated
1223df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian            // (pushed to the framebuffer).
122495a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian            // This is needed because PARTIAL_UPDATES only takes one
12250f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian            // rectangle instead of a region (see DisplayDevice::flip())
12264297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            dirtyRegion.set(hw->swapRegion.bounds());
1227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
122829d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // we need to redraw everything (the whole screen)
12294297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            dirtyRegion.set(hw->bounds());
12304297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->swapRegion = dirtyRegion;
1231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1233edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1234cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    doComposeSurfaces(hw, dirtyRegion);
1235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1236cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    // FIXME: we need to call eglSwapBuffers() on displays that have
1237cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    // GL composition and only on those.
1238cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    // however, currently hwc.commit() already does that for the main
1239cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    // display and never for the other ones
1240cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (hw->getDisplayId() >= DisplayDevice::DISPLAY_ID_COUNT) {
1241cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        // FIXME: EGL spec says:
1242cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        //   "surface must be bound to the calling thread's current context,
1243cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        //    for the current rendering API."
1244cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        eglSwapBuffers(mEGLDisplay, hw->getEGLSurface());
1245d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    }
1246d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
12479c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    // update the swap region and clear the dirty region
12484297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->swapRegion.orSelf(dirtyRegion);
1249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1251cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& hw, const Region& dirty)
1252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
12538630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    HWComposer& hwc(getHwComposer());
12541e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian    int32_t id = hw->getDisplayId();
12551e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian    HWComposer::LayerListIterator cur = hwc.begin(id);
12561e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian    const HWComposer::LayerListIterator end = hwc.end(id);
1257a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
12581e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian    const size_t fbLayerCount = hwc.getLayerCount(id, HWC_FRAMEBUFFER);
125952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    if (cur==end || fbLayerCount) {
1260a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
12610f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian        DisplayDevice::makeCurrent(hw, mEGLContext);
1262a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
126352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        // set the frame buffer
126452bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        glMatrixMode(GL_MODELVIEW);
126552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        glLoadIdentity();
1266a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
1267a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        // Never touch the framebuffer if we don't have any framebuffer layers
12681e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian        if (hwc.getLayerCount(id, HWC_OVERLAY)) {
1269b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // when using overlays, we assume a fully transparent framebuffer
1270b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // NOTE: we could reduce how much we need to clear, for instance
1271b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // remove where there are opaque FB layers. however, on some
1272b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // GPUs doing a "clean slate" glClear might be more efficient.
1273b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // We'll revisit later if needed.
1274b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            glClearColor(0, 0, 0, 0);
1275b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            glClear(GL_COLOR_BUFFER_BIT);
1276b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian        } else {
12774297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            const Region region(hw->undefinedRegion.intersect(dirty));
1278b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // screen is already cleared here
127987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            if (!region.isEmpty()) {
1280b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                // can happen with SurfaceView
128187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian                drawWormhole(region);
1282b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            }
1283a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        }
12844b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian
1285a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        /*
1286a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian         * and then, render the layers targeted at the framebuffer
1287a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian         */
12884b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian
12894297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const Vector< sp<LayerBase> >& layers(hw->getVisibleLayersSortedByZ());
1290a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        const size_t count = layers.size();
12914297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const Transform& tr = hw->getTransform();
1292a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall        for (size_t i=0 ; i<count ; ++i) {
1293a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian            const sp<LayerBase>& layer(layers[i]);
12944fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region clip(dirty.intersect(tr.transform(layer->visibleRegion)));
1295cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            if (cur != end) {
1296cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                // we're using h/w composer
1297cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                if (!clip.isEmpty()) {
1298cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                    if (cur->getCompositionType() == HWC_OVERLAY) {
1299cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                        if (i && (cur->getHints() & HWC_HINT_CLEAR_FB)
1300cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                                && layer->isOpaque()) {
1301cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            // never clear the very first layer since we're
1302cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            // guaranteed the FB is already cleared
1303cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            layer->clearWithOpenGL(hw, clip);
1304cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                        }
1305cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                    } else {
1306cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                        layer->draw(hw, clip);
1307a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                    }
1308cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                    layer->setAcquireFence(hw, *cur);
1309a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                }
1310a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall                ++cur;
1311cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            } else {
1312cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                // we're not using h/w composer
1313cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                if (!clip.isEmpty()) {
1314cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                    layer->draw(hw, clip);
1315cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                }
1316a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall            }
13174b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian        }
13184b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian    }
1319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
132187baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::drawWormhole(const Region& region) const
1322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1323f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    glDisable(GL_TEXTURE_EXTERNAL_OES);
1324b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian    glDisable(GL_TEXTURE_2D);
1325f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    glDisable(GL_BLEND);
1326b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian    glColor4f(0,0,0,0);
1327f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian
1328f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    GLfloat vertices[4][2];
1329f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    glVertexPointer(2, GL_FLOAT, 0, vertices);
1330f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    Region::const_iterator it = region.begin();
1331f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    Region::const_iterator const end = region.end();
1332f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    while (it != end) {
1333f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        const Rect& r = *it++;
1334f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[0][0] = r.left;
1335f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[0][1] = r.top;
1336f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[1][0] = r.right;
1337f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[1][1] = r.top;
1338f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[2][0] = r.right;
1339f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[2][1] = r.bottom;
1340f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[3][0] = r.left;
1341f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[3][1] = r.bottom;
1342f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1343f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    }
1344edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1345edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
134696f0819f81293076e652792794a961543e6750d7Mathias Agopianssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
134796f0819f81293076e652792794a961543e6750d7Mathias Agopian        const sp<LayerBaseClient>& lbc)
13481b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
134996f0819f81293076e652792794a961543e6750d7Mathias Agopian    // attach this layer to the client
13504f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    size_t name = client->attachLayer(lbc);
13514f113740180b6512b43723c4728f262882dc9b45Mathias Agopian
135296f0819f81293076e652792794a961543e6750d7Mathias Agopian    // add this layer to the current state list
1353921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    Mutex::Autolock _l(mStateLock);
1354921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    mCurrentState.layersSortedByZ.add(lbc);
135596f0819f81293076e652792794a961543e6750d7Mathias Agopian
13564f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    return ssize_t(name);
135796f0819f81293076e652792794a961543e6750d7Mathias Agopian}
135896f0819f81293076e652792794a961543e6750d7Mathias Agopian
135996f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer)
136096f0819f81293076e652792794a961543e6750d7Mathias Agopian{
136196f0819f81293076e652792794a961543e6750d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
136296f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = purgatorizeLayer_l(layer);
136396f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR)
13643559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        setTransactionFlags(eTransactionNeeded);
136596f0819f81293076e652792794a961543e6750d7Mathias Agopian    return err;
1366edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1367edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1368076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase)
1369edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1370edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase);
1371edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (index >= 0) {
1372076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved = true;
1373edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
1374edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
13753d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    return status_t(index);
1376edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1377edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
13789a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase)
13799a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
138076cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    // First add the layer to the purgatory list, which makes sure it won't
138176cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    // go away, then remove it from the main list (through a transaction).
13829a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    ssize_t err = removeLayer_l(layerBase);
138376cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    if (err >= 0) {
138476cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian        mLayerPurgatory.add(layerBase);
138576cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    }
13868c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian
13872f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall    mLayersPendingRemoval.push(layerBase);
13880b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian
13893d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // it's possible that we don't find a layer, because it might
13903d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // have been destroyed already -- this is not technically an error
139196f0819f81293076e652792794a961543e6750d7Mathias Agopian    // from the user because there is a race between Client::destroySurface(),
139296f0819f81293076e652792794a961543e6750d7Mathias Agopian    // ~Client() and ~ISurface().
13939a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err;
13949a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
13959a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
1396dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopianuint32_t SurfaceFlinger::peekTransactionFlags(uint32_t flags)
1397dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian{
1398dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian    return android_atomic_release_load(&mTransactionFlags);
1399dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian}
1400dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian
1401edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags)
1402edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1403edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return android_atomic_and(~flags, &mTransactionFlags) & flags;
1404edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1405edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1406bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags)
1407edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1408edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t old = android_atomic_or(flags, &mTransactionFlags);
1409edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((old & flags)==0) { // wake the server up
141099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        signalTransaction();
1411edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1412edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return old;
1413edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1414edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
14158b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopianvoid SurfaceFlinger::setTransactionState(
14168b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        const Vector<ComposerState>& state,
14178b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        const Vector<DisplayState>& displays,
14188b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        uint32_t flags)
14198b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian{
1420698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
142128378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    uint32_t transactionFlags = 0;
1422e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
1423e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    size_t count = displays.size();
1424e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
1425e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const DisplayState& s(displays[i]);
1426e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        transactionFlags |= setDisplayStateLocked(s);
1427b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis    }
1428b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis
1429e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    count = state.size();
1430698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
1431698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const ComposerState& s(state[i]);
1432698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        sp<Client> client( static_cast<Client *>(s.client.get()) );
143328378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        transactionFlags |= setClientStateLocked(client, s.state);
1434698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    }
1435386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian
143628378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    if (transactionFlags) {
1437386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // this triggers the transaction
143828378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        setTransactionFlags(transactionFlags);
1439698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian
1440386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // if this is a synchronous transaction, wait for it to take effect
1441386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // before returning.
1442386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        if (flags & eSynchronous) {
1443386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            mTransationPending = true;
1444386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        }
1445386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        while (mTransationPending) {
1446386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
1447386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            if (CC_UNLIKELY(err != NO_ERROR)) {
1448386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                // just in case something goes wrong in SF, return to the
1449386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                // called after a few seconds.
145032397c1cd3327905173b36baa6fd1c579bc328ffSteve Block                ALOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!");
1451386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                mTransationPending = false;
1452386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                break;
1453386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            }
1454cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        }
1455edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1456edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1457edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1458e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setDisplayStateLocked(const DisplayState& s)
1459e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{
1460e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    uint32_t flags = 0;
1461e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    DisplayDeviceState& disp(mCurrentState.displays.editValueFor(s.token));
1462e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    if (disp.id >= 0) {
1463e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const uint32_t what = s.what;
1464e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & DisplayState::eSurfaceChanged) {
1465e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.surface->asBinder() != s.surface->asBinder()) {
1466e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.surface = s.surface;
1467e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
1468e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1469e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1470e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & DisplayState::eLayerStackChanged) {
1471e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.layerStack != s.layerStack) {
1472e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.layerStack = s.layerStack;
1473e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
1474e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1475e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1476818b46058aa3006e1d3c178abd36d4f10823f5d9Mathias Agopian        if (what & DisplayState::eOrientationChanged) {
1477e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.orientation != s.orientation) {
1478e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.orientation = s.orientation;
1479e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
1480e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1481818b46058aa3006e1d3c178abd36d4f10823f5d9Mathias Agopian        }
1482818b46058aa3006e1d3c178abd36d4f10823f5d9Mathias Agopian        if (what & DisplayState::eFrameChanged) {
1483e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.frame != s.frame) {
1484e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.frame = s.frame;
1485e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
1486e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1487818b46058aa3006e1d3c178abd36d4f10823f5d9Mathias Agopian        }
1488818b46058aa3006e1d3c178abd36d4f10823f5d9Mathias Agopian        if (what & DisplayState::eViewportChanged) {
1489e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.viewport != s.viewport) {
1490e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.viewport = s.viewport;
1491e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
1492e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1493e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1494e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
1495e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return flags;
1496e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
1497e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
1498e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setClientStateLocked(
1499e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const sp<Client>& client,
1500e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const layer_state_t& s)
1501e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{
1502e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    uint32_t flags = 0;
1503e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    sp<LayerBaseClient> layer(client->getLayerUser(s.surface));
1504e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    if (layer != 0) {
1505e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const uint32_t what = s.what;
1506e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::ePositionChanged) {
1507e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setPosition(s.x, s.y))
1508e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1509e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1510e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eLayerChanged) {
1511e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            // NOTE: index needs to be calculated before we update the state
1512e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
1513e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setLayer(s.z)) {
1514e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.removeAt(idx);
1515e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.add(layer);
1516e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // we need traversal (state changed)
1517e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // AND transaction (list changed)
1518e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTransactionNeeded|eTraversalNeeded;
1519e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1520e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1521e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eSizeChanged) {
1522e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setSize(s.w, s.h)) {
1523e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1524e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1525e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1526e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eAlphaChanged) {
1527e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f)))
1528e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1529e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1530e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eMatrixChanged) {
1531e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setMatrix(s.matrix))
1532e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1533e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1534e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eTransparentRegionChanged) {
1535e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setTransparentRegionHint(s.transparentRegion))
1536e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1537e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1538e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eVisibilityChanged) {
1539e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setFlags(s.flags, s.mask))
1540e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1541e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1542e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eCropChanged) {
1543e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setCrop(s.crop))
1544e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1545e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1546e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eLayerStackChanged) {
1547e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            // NOTE: index needs to be calculated before we update the state
1548e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
1549e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setLayerStack(s.layerStack)) {
1550e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.removeAt(idx);
1551e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.add(layer);
1552e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // we need traversal (state changed)
1553e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // AND transaction (list changed)
1554e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTransactionNeeded|eTraversalNeeded;
1555e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1556e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1557e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
1558e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return flags;
1559e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
1560e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
1561921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopiansp<ISurface> SurfaceFlinger::createLayer(
15620ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        ISurfaceComposerClient::surface_data_t* params,
15630ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const String8& name,
15640ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const sp<Client>& client,
1565edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        DisplayID d, uint32_t w, uint32_t h, PixelFormat format,
1566edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t flags)
1567edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1568076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBaseClient> layer;
1569a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    sp<ISurface> surfaceHandle;
15706e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian
15716e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    if (int32_t(w|h) < 0) {
1572921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        ALOGE("createLayer() failed, w or h is negative (w=%d, h=%d)",
15736e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian                int(w), int(h));
15746e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian        return surfaceHandle;
15756e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    }
15768b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
1577921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    //ALOGD("createLayer for (%d x %d), name=%s", w, h, name.string());
15783165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian    switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {
15793165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        case ISurfaceComposerClient::eFXSurfaceNormal:
1580921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian            layer = createNormalLayer(client, d, w, h, flags, format);
1581edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
15823165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        case ISurfaceComposerClient::eFXSurfaceBlur:
15833165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        case ISurfaceComposerClient::eFXSurfaceDim:
1584921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian            layer = createDimLayer(client, d, w, h, flags);
1585edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
15863165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        case ISurfaceComposerClient::eFXSurfaceScreenshot:
1587921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian            layer = createScreenshotLayer(client, d, w, h, flags);
1588118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian            break;
1589edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1590edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1591076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (layer != 0) {
159296f0819f81293076e652792794a961543e6750d7Mathias Agopian        layer->initStates(w, h, flags);
1593285dbde2e0cd0057be070ded3be8f5f453147edcMathias Agopian        layer->setName(name);
159496f0819f81293076e652792794a961543e6750d7Mathias Agopian        ssize_t token = addClientLayer(client, layer);
1595edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        surfaceHandle = layer->getSurface();
15968b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber        if (surfaceHandle != 0) {
159796f0819f81293076e652792794a961543e6750d7Mathias Agopian            params->token = token;
1598a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            params->identity = layer->getIdentity();
15991c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        }
160096f0819f81293076e652792794a961543e6750d7Mathias Agopian        setTransactionFlags(eTransactionNeeded);
1601edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1602edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1603edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return surfaceHandle;
1604edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1605edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1606921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopiansp<Layer> SurfaceFlinger::createNormalLayer(
1607f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        const sp<Client>& client, DisplayID display,
160896f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags,
16091c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        PixelFormat& format)
1610edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1611edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize the surfaces
161292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    switch (format) {
1613edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSPARENT:
1614edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSLUCENT:
1615edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        format = PIXEL_FORMAT_RGBA_8888;
1616edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1617edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_OPAQUE:
1618a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888
1619a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian        format = PIXEL_FORMAT_RGB_565;
1620a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#else
16218f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian        format = PIXEL_FORMAT_RGBX_8888;
1622a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif
1623edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1624edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1625edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1626a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888
1627a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian    if (format == PIXEL_FORMAT_RGBX_8888)
1628a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian        format = PIXEL_FORMAT_RGBA_8888;
1629a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif
1630a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian
163196f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<Layer> layer = new Layer(this, display, client);
1632f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian    status_t err = layer->setBuffers(w, h, format, flags);
163399ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten    if (CC_LIKELY(err != NO_ERROR)) {
1634921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        ALOGE("createNormalLayer() failed (%s)", strerror(-err));
1635076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        layer.clear();
1636edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1637edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1638edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1639edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1640921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopiansp<LayerDim> SurfaceFlinger::createDimLayer(
1641f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        const sp<Client>& client, DisplayID display,
164296f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags)
1643edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
164496f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<LayerDim> layer = new LayerDim(this, display, client);
1645118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    return layer;
1646118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
1647118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
1648921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopiansp<LayerScreenshot> SurfaceFlinger::createScreenshotLayer(
1649118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        const sp<Client>& client, DisplayID display,
1650118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags)
1651118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{
1652118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    sp<LayerScreenshot> layer = new LayerScreenshot(this, display, client);
1653edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1654edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1655edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1656921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianstatus_t SurfaceFlinger::onLayerRemoved(const sp<Client>& client, SurfaceID sid)
16579a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
16589a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    /*
16599a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     * called by the window manager, when a surface should be marked for
16609a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     * destruction.
16618b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber     *
16620aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * The surface is removed from the current and drawing lists, but placed
16630aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * in the purgatory queue, so it's not destroyed right-away (we need
16640aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * to wait for all client's references to go away first).
16659a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     */
16669a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
166748d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    status_t err = NAME_NOT_FOUND;
16680aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian    Mutex::Autolock _l(mStateLock);
166996f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<LayerBaseClient> layer = client->getLayerUser(sid);
1670b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam
167148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    if (layer != 0) {
167248d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        err = purgatorizeLayer_l(layer);
167348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        if (err == NO_ERROR) {
167413233e067b8f71adc3a0ade5f442265e1f27084bMathias Agopian            setTransactionFlags(eTransactionNeeded);
167548d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        }
16769a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    }
16779a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return err;
16789a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
16799a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
1680921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianstatus_t SurfaceFlinger::onLayerDestroyed(const wp<LayerBaseClient>& layer)
1681edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1682759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian    // called by ~ISurface() when all references are gone
1683ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    status_t err = NO_ERROR;
1684ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    sp<LayerBaseClient> l(layer.promote());
1685ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    if (l != NULL) {
1686ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        Mutex::Autolock _l(mStateLock);
1687ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        err = removeLayer_l(l);
1688ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        if (err == NAME_NOT_FOUND) {
1689ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // The surface wasn't in the current list, which means it was
1690ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // removed already, which means it is in the purgatory,
1691ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // and need to be removed from there.
1692ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            ssize_t idx = mLayerPurgatory.remove(l);
1693e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block            ALOGE_IF(idx < 0,
1694ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian                    "layer=%p is not in the purgatory list", l.get());
1695f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        }
1696e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE_IF(err<0 && err != NAME_NOT_FOUND,
1697ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian                "error removing layer=%p (%s)", l.get(), strerror(-err));
1698ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    }
1699ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    return err;
1700edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1701edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1702b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// ---------------------------------------------------------------------------
1703b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
1704b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopianvoid SurfaceFlinger::onScreenAcquired() {
17058e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross    ALOGD("Screen about to return, flinger = %p", this);
17064297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    sp<const DisplayDevice> hw(getDefaultDisplayDevice()); // XXX: this should be per DisplayDevice
17078630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    getHwComposer().acquire();
17084297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->acquireScreen();
170922ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian    mEventThread->onScreenAcquired();
171020128300e0cb7f459a60cfbcddb48190ce6545edMathias Agopian    mVisibleRegionsDirty = true;
171120128300e0cb7f459a60cfbcddb48190ce6545edMathias Agopian    repaintEverything();
1712edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1713edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1714b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopianvoid SurfaceFlinger::onScreenReleased() {
17158e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross    ALOGD("About to give-up screen, flinger = %p", this);
17164297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    sp<const DisplayDevice> hw(getDefaultDisplayDevice()); // XXX: this should be per DisplayDevice
17174297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    if (hw->isScreenAcquired()) {
171822ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian        mEventThread->onScreenReleased();
17194297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        hw->releaseScreen();
17208630320433bd15aca239522e54e711ef6372ab07Mathias Agopian        getHwComposer().release();
1721b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        // from this point on, SF will stop drawing
1722b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    }
1723b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian}
1724b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
17258e533069e5721e55cb9768e140e16546c3a4a8b6Colin Crossvoid SurfaceFlinger::unblank() {
1726b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    class MessageScreenAcquired : public MessageBase {
1727b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        SurfaceFlinger* flinger;
1728b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    public:
1729b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        MessageScreenAcquired(SurfaceFlinger* flinger) : flinger(flinger) { }
1730b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        virtual bool handler() {
1731b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            flinger->onScreenAcquired();
1732b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            return true;
1733b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        }
1734b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    };
1735b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    sp<MessageBase> msg = new MessageScreenAcquired(this);
1736b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    postMessageSync(msg);
1737edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1738edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
17398e533069e5721e55cb9768e140e16546c3a4a8b6Colin Crossvoid SurfaceFlinger::blank() {
1740b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    class MessageScreenReleased : public MessageBase {
1741b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        SurfaceFlinger* flinger;
1742b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    public:
1743b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        MessageScreenReleased(SurfaceFlinger* flinger) : flinger(flinger) { }
1744b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        virtual bool handler() {
1745b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            flinger->onScreenReleased();
1746b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            return true;
1747b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        }
1748b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    };
1749b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    sp<MessageBase> msg = new MessageScreenReleased(this);
1750b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    postMessageSync(msg);
1751b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian}
1752b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
1753b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// ---------------------------------------------------------------------------
1754b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
1755edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
1756edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
17571d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling    const size_t SIZE = 4096;
1758edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char buffer[SIZE];
1759edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    String8 result;
176099b49840d309727678b77403d6cc9f920111623fMathias Agopian
176199b49840d309727678b77403d6cc9f920111623fMathias Agopian    if (!PermissionCache::checkCallingPermission(sDump)) {
1762edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        snprintf(buffer, SIZE, "Permission Denial: "
1763edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                "can't dump SurfaceFlinger from pid=%d, uid=%d\n",
1764edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                IPCThreadState::self()->getCallingPid(),
1765edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                IPCThreadState::self()->getCallingUid());
1766edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        result.append(buffer);
1767edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
17689795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // Try to get the main lock, but don't insist if we can't
17699795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // (this would indicate SF is stuck, but we want to be able to
17709795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // print something in dumpsys).
17719795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        int retry = 3;
17729795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        while (mStateLock.tryLock()<0 && --retry>=0) {
17739795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            usleep(1000000);
17749795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
17759795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const bool locked(retry >= 0);
17769795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (!locked) {
17778b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber            snprintf(buffer, SIZE,
17789795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "SurfaceFlinger appears to be unresponsive, "
17799795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "dumping anyways (no locks held)\n");
17809795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            result.append(buffer);
17819795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
17829795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
178382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        bool dumpAll = true;
178482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        size_t index = 0;
178525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        size_t numArgs = args.size();
178625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        if (numArgs) {
178725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
178825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--list"))) {
178925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                index++;
179025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                listLayersLocked(args, index, result, buffer, SIZE);
179135aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
179225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            }
179325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
179425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
179525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--latency"))) {
179682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                index++;
179782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                dumpStatsLocked(args, index, result, buffer, SIZE);
179835aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
179982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            }
180025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
180125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
180225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--latency-clear"))) {
180325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                index++;
180425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                clearStatsLocked(args, index, result, buffer, SIZE);
180535aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
180625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            }
1807edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
18081b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
180982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (dumpAll) {
181082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            dumpAllLocked(result, buffer, SIZE);
181182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
181248b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
181382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (locked) {
181482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mStateLock.unlock();
181548b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        }
181682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
181782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    write(fd, result.string(), result.size());
181882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    return NO_ERROR;
181982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
182048b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
182125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::listLayersLocked(const Vector<String16>& args, size_t& index,
182225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        String8& result, char* buffer, size_t SIZE) const
182325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
182425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
182525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const size_t count = currentLayers.size();
182625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
182725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
182825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        snprintf(buffer, SIZE, "%s\n", layer->getName().string());
182925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        result.append(buffer);
183025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
183125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
183225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
183382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index,
183482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        String8& result, char* buffer, size_t SIZE) const
183582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
183682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    String8 name;
183782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    if (index < args.size()) {
183882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        name = String8(args[index]);
183982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        index++;
184082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
184148b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
184282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
184382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const size_t count = currentLayers.size();
184482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    for (size_t i=0 ; i<count ; i++) {
184582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
184682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (name.isEmpty()) {
184782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            snprintf(buffer, SIZE, "%s\n", layer->getName().string());
184882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            result.append(buffer);
184982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
185082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (name.isEmpty() || (name == layer->getName())) {
185182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            layer->dumpStats(result, buffer, SIZE);
185282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
185382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
185482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
1855ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian
185625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& index,
185725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        String8& result, char* buffer, size_t SIZE) const
185825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
185925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    String8 name;
186025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    if (index < args.size()) {
186125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        name = String8(args[index]);
186225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        index++;
186325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
186425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
186525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
186625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const size_t count = currentLayers.size();
186725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
186825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
186925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        if (name.isEmpty() || (name == layer->getName())) {
187025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            layer->clearStats();
187125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        }
187225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
187325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
187425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
187582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpAllLocked(
187682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        String8& result, char* buffer, size_t SIZE) const
187782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
187882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    // figure out if we're stuck somewhere
187982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t now = systemTime();
188082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t inSwapBuffers(mDebugInSwapBuffers);
188182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t inTransaction(mDebugInTransaction);
188282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0;
188382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0;
1884bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
188582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
188682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump the visible layer list
188782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
188882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
188982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const size_t count = currentLayers.size();
189082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "Visible layers (count = %d)\n", count);
189182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
189282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    for (size_t i=0 ; i<count ; i++) {
189382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
189482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        layer->dump(result, buffer, SIZE);
189582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
1896bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
189782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
189882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump the layers in the purgatory
189982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
1900ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian
190182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const size_t purgatorySize = mLayerPurgatory.size();
190282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "Purgatory state (%d entries)\n", purgatorySize);
190382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
190482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    for (size_t i=0 ; i<purgatorySize ; i++) {
190582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
190682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        layer->shortDump(result, buffer, SIZE);
190782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
19081b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
190982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
19105f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian     * Dump Display state
19115f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian     */
19125f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian
19135f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
19145f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        const sp<const DisplayDevice>& hw(mDisplays[dpy]);
19155f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        snprintf(buffer, SIZE,
19165f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian                "+ DisplayDevice[%u]\n"
19175f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian                "   id=%x, layerStack=%u, (%4dx%4d), orient=%2d, tr=%08x, "
19185f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian                "flips=%u, secure=%d, numLayers=%u\n",
19195f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian                dpy,
19205f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian                hw->getDisplayId(), hw->getLayerStack(),
19215f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian                hw->getWidth(), hw->getHeight(),
19225f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian                hw->getOrientation(), hw->getTransform().getType(),
19235f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian                hw->getPageFlipCount(),
19245f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian                hw->getSecureLayerVisible(),
19255f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian                hw->getVisibleLayersSortedByZ().size());
19265f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        result.append(buffer);
19275f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    }
19285f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian
19295f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    /*
193082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump SurfaceFlinger global state
193182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
19321b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
193382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "SurfaceFlinger global state:\n");
193482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
19351b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
1936888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian    HWComposer& hwc(getHwComposer());
19374297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    sp<const DisplayDevice> hw(getDefaultDisplayDevice());
193882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const GLExtensions& extensions(GLExtensions::getInstance());
193982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "GLES: %s, %s, %s\n",
194082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            extensions.getVendor(),
194182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            extensions.getRenderer(),
194282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            extensions.getVersion());
194382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
1944d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
194582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "EGL : %s\n",
1946d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian            eglQueryString(mEGLDisplay, EGL_VERSION_HW_ANDROID));
194782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
194873d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian
194982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "EXTS: %s\n", extensions.getExtension());
195082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
19519795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
19524297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->undefinedRegion.dump(result, "undefinedRegion");
195382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE,
195482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  orientation=%d, canDraw=%d\n",
19554297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->getOrientation(), hw->canDraw());
195682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
195782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE,
195882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  last eglSwapBuffers() time: %f us\n"
195982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  last transaction time     : %f us\n"
1960c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian            "  transaction-flags         : %08x\n"
196182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  refresh-rate              : %f fps\n"
196282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  x-dpi                     : %f\n"
19638b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            "  y-dpi                     : %f\n",
196482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mLastSwapBufferTime/1000.0,
196582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mLastTransactionTime/1000.0,
1966c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian            mTransactionFlags,
1967888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian            1e9 / hwc.getRefreshPeriod(),
19688b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            hwc.getDpiX(),
19698b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            hwc.getDpiY());
197082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
197182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
197282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "  eglSwapBuffers time: %f us\n",
197382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            inSwapBuffersDuration/1000.0);
197482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
197582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
197682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "  transaction time: %f us\n",
197782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            inTransactionDuration/1000.0);
197882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
197982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
198082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
198182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * VSYNC state
198282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
198382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    mEventThread->dump(result, buffer, SIZE);
198482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
198582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
198682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump HWComposer state
198782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
198882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "h/w composer state:\n");
198982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
199082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "  h/w composer %s and %s\n",
199182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            hwc.initCheck()==NO_ERROR ? "present" : "not present",
199282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                    (mDebugDisableHWC || mDebugRegion) ? "disabled" : "enabled");
199382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
19944297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hwc.dump(result, buffer, SIZE, hw->getVisibleLayersSortedByZ());
199582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
199682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
199782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump gralloc state
199882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
199982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
200082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    alloc.dump(result);
20014297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->dump(result);
2002edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2003edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2004edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::onTransact(
2005edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
2006edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2007edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (code) {
2008edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case CREATE_CONNECTION:
2009698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        case SET_TRANSACTION_STATE:
2010edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case BOOT_FINISHED:
20118e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross        case BLANK:
20128e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross        case UNBLANK:
2013edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        {
2014edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // codes that require permission check
2015edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            IPCThreadState* ipc = IPCThreadState::self();
2016edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int pid = ipc->getCallingPid();
2017a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian            const int uid = ipc->getCallingUid();
201899b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
201999b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) {
2020e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block                ALOGE("Permission Denial: "
2021375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                        "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
2022375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                return PERMISSION_DENIED;
2023edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
20241b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
20251b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
20261b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        case CAPTURE_SCREEN:
20271b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
20281b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            // codes that require permission check
20291b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
20301b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int pid = ipc->getCallingPid();
20311b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int uid = ipc->getCallingUid();
203299b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
203399b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) {
2034e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block                ALOGE("Permission Denial: "
20351b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                        "can't read framebuffer pid=%d, uid=%d", pid, uid);
20361b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                return PERMISSION_DENIED;
20371b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            }
20381b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
2039edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
2040edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
20411b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
2042edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
2043edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
2044b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        CHECK_INTERFACE(ISurfaceComposer, data, reply);
204599ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten        if (CC_UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) {
2046375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
2047375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int pid = ipc->getCallingPid();
2048375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int uid = ipc->getCallingUid();
2049e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block            ALOGE("Permission Denial: "
2050375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                    "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
2051edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return PERMISSION_DENIED;
2052edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
2053edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int n;
2054edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        switch (code) {
205501b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian            case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE
205635b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian            case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE
2057edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
2058edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1002:  // SHOW_UPDATES
2059edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                n = data.readInt32();
2060edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDebugRegion = n ? n : (mDebugRegion ? 0 : 1);
206153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
206253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
2063edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
2064edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1004:{ // repaint everything
206553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
2066cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
2067cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            }
2068cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            case 1005:{ // force transaction
2069e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                setTransactionFlags(
2070e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        eTransactionNeeded|
2071e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        eDisplayTransactionNeeded|
2072e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        eTraversalNeeded);
2073cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
2074edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
20754d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            case 1006:{ // send empty update
20764d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian                signalRefresh();
20774d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian                return NO_ERROR;
20784d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            }
207953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian            case 1008:  // toggle use of hw composer
208053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                n = data.readInt32();
208153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                mDebugDisableHWC = n ? 1 : 0;
208253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
208353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
208453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                return NO_ERROR;
2085a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian            case 1009:  // toggle use of transform hint
2086a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                n = data.readInt32();
2087a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                mDebugDisableTransformHint = n ? 1 : 0;
2088a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                invalidateHwcGeometry();
2089a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                repaintEverything();
2090a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                return NO_ERROR;
2091edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1010:  // interrogate.
209201b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian                reply->writeInt32(0);
2093edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(0);
2094edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(mDebugRegion);
2095b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                reply->writeInt32(0);
209612839bee29bdcc65731b4d42029cc59e2320c5c4Dianne Hackborn                reply->writeInt32(mDebugDisableHWC);
2097edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
2098edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1013: {
2099edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                Mutex::Autolock _l(mStateLock);
21004297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                sp<const DisplayDevice> hw(getDefaultDisplayDevice());
21014297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                reply->writeInt32(hw->getPageFlipCount());
2102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
2103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return NO_ERROR;
2104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
2105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return err;
2107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
210953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopianvoid SurfaceFlinger::repaintEverything() {
211087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    android_atomic_or(1, &mRepaintEverything);
211199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    signalTransaction();
211253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian}
211353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian
211459119e658a12279e8fff508f8773843de2d90917Mathias Agopian// ---------------------------------------------------------------------------
211559119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2116118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopianstatus_t SurfaceFlinger::renderScreenToTexture(DisplayID dpy,
2117118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        GLuint* textureName, GLfloat* uOut, GLfloat* vOut)
2118118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{
2119118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    Mutex::Autolock _l(mStateLock);
2120118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    return renderScreenToTextureLocked(dpy, textureName, uOut, vOut);
2121118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
2122118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
21239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::renderScreenToTextureLocked(DisplayID dpy,
21249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        GLuint* textureName, GLfloat* uOut, GLfloat* vOut)
212559119e658a12279e8fff508f8773843de2d90917Mathias Agopian{
212622ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian    ATRACE_CALL();
212722ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian
212859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
212959119e658a12279e8fff508f8773843de2d90917Mathias Agopian        return INVALID_OPERATION;
213059119e658a12279e8fff508f8773843de2d90917Mathias Agopian
213159119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // get screen geometry
21324297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    sp<const DisplayDevice> hw(getDisplayDevice(dpy));
21334297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const uint32_t hw_w = hw->getWidth();
21344297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const uint32_t hw_h = hw->getHeight();
213559119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLfloat u = 1;
213659119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLfloat v = 1;
213759119e658a12279e8fff508f8773843de2d90917Mathias Agopian
213859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // make sure to clear all GL error flags
213959119e658a12279e8fff508f8773843de2d90917Mathias Agopian    while ( glGetError() != GL_NO_ERROR ) ;
214059119e658a12279e8fff508f8773843de2d90917Mathias Agopian
214159119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // create a FBO
214259119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLuint name, tname;
214359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glGenTextures(1, &tname);
214459119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
2145a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2146a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
21479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
21489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            hw_w, hw_h, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
214959119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (glGetError() != GL_NO_ERROR) {
2150015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian        while ( glGetError() != GL_NO_ERROR ) ;
215159119e658a12279e8fff508f8773843de2d90917Mathias Agopian        GLint tw = (2 << (31 - clz(hw_w)));
215259119e658a12279e8fff508f8773843de2d90917Mathias Agopian        GLint th = (2 << (31 - clz(hw_h)));
21539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
21549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian                tw, th, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
215559119e658a12279e8fff508f8773843de2d90917Mathias Agopian        u = GLfloat(hw_w) / tw;
215659119e658a12279e8fff508f8773843de2d90917Mathias Agopian        v = GLfloat(hw_h) / th;
215759119e658a12279e8fff508f8773843de2d90917Mathias Agopian    }
215859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glGenFramebuffersOES(1, &name);
215959119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
21609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES,
21619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0);
216259119e658a12279e8fff508f8773843de2d90917Mathias Agopian
21639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // redraw the screen entirely...
2164c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_EXTERNAL_OES);
2165c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_2D);
21669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glClearColor(0,0,0,1);
21679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glClear(GL_COLOR_BUFFER_BIT);
2168a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glMatrixMode(GL_MODELVIEW);
2169a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glLoadIdentity();
21704297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const Vector< sp<LayerBase> >& layers(hw->getVisibleLayersSortedByZ());
21719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const size_t count = layers.size();
21729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (size_t i=0 ; i<count ; ++i) {
21739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
2174fcb239d3dac8bc80f28177f1951611c1d43286ffMathias Agopian        layer->draw(hw);
21759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
217659119e658a12279e8fff508f8773843de2d90917Mathias Agopian
21774297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->compositionComplete();
2178118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
21799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // back to main framebuffer
21809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
21819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDeleteFramebuffersOES(1, &name);
218259119e658a12279e8fff508f8773843de2d90917Mathias Agopian
21839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *textureName = tname;
21849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *uOut = u;
21859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *vOut = v;
21869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
21879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
218859119e658a12279e8fff508f8773843de2d90917Mathias Agopian
21899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// ---------------------------------------------------------------------------
21909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
219174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopianstatus_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy,
219274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        sp<IMemoryHeap>* heap,
219374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t* w, uint32_t* h, PixelFormat* f,
2194bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t sw, uint32_t sh,
2195bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ, uint32_t maxLayerZ)
219674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{
2197fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian    ATRACE_CALL();
2198fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian
219974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    status_t result = PERMISSION_DENIED;
220074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
220174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // only one display supported for now
22023b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    if (CC_UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) {
2203ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian        ALOGE("invalid display %d", dpy);
220474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return BAD_VALUE;
22053b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
220674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
22073b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject()) {
220874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return INVALID_OPERATION;
22093b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
221074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
221174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // get screen geometry
22124297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    sp<const DisplayDevice> hw(getDisplayDevice(dpy));
22134297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const uint32_t hw_w = hw->getWidth();
22144297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const uint32_t hw_h = hw->getHeight();
221574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
22163b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    // if we have secure windows on this display, never allow the screen capture
22174297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    if (hw->getSecureLayerVisible()) {
2218ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian        ALOGW("FB is protected: PERMISSION_DENIED");
22193b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        return PERMISSION_DENIED;
22203b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
22213b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
22223b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    if ((sw > hw_w) || (sh > hw_h)) {
2223ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian        ALOGE("size mismatch (%d, %d) > (%d, %d)", sw, sh, hw_w, hw_h);
222474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return BAD_VALUE;
22253b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
222674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
222774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    sw = (!sw) ? hw_w : sw;
222874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    sh = (!sh) ? hw_h : sh;
222974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const size_t size = sw * sh * 4;
2230fcb239d3dac8bc80f28177f1951611c1d43286ffMathias Agopian    const bool filtering = sw != hw_w || sh != hw_h;
223174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
2232ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian//    ALOGD("screenshot: sw=%d, sh=%d, minZ=%d, maxZ=%d",
2233ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian//            sw, sh, minLayerZ, maxLayerZ);
2234c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
223574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // make sure to clear all GL error flags
223674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    while ( glGetError() != GL_NO_ERROR ) ;
223774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
223874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // create a FBO
223974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    GLuint name, tname;
224074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glGenRenderbuffersOES(1, &tname);
224174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindRenderbufferOES(GL_RENDERBUFFER_OES, tname);
224274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA8_OES, sw, sh);
2243fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian
224474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glGenFramebuffersOES(1, &name);
224574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
224674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES,
224774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, tname);
224874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
224974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
2250c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
225174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    if (status == GL_FRAMEBUFFER_COMPLETE_OES) {
225274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
225374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // invert everything, b/c glReadPixel() below will invert the FB
225474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glViewport(0, 0, sw, sh);
225574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_PROJECTION);
225674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glPushMatrix();
225774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glLoadIdentity();
2258ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian        glOrthof(0, hw_w, hw_h, 0, 0, 1);
225974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_MODELVIEW);
226074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
226174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // redraw the screen entirely...
226274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glClearColor(0,0,0,1);
226374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
2264f653b897a449e10d6cbfb6e0812f7b0bb02d6482Mathias Agopian
22659575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        const LayerVector& layers(mDrawingState.layersSortedByZ);
22669575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        const size_t count = layers.size();
226774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        for (size_t i=0 ; i<count ; ++i) {
226874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            const sp<LayerBase>& layer(layers[i]);
2269b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian            const uint32_t flags = layer->drawingState().flags;
22703165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian            if (!(flags & layer_state_t::eLayerHidden)) {
2271b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                const uint32_t z = layer->drawingState().z;
2272b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                if (z >= minLayerZ && z <= maxLayerZ) {
2273fcb239d3dac8bc80f28177f1951611c1d43286ffMathias Agopian                    if (filtering) layer->setFiltering(true);
2274fcb239d3dac8bc80f28177f1951611c1d43286ffMathias Agopian                    layer->draw(hw);
2275fcb239d3dac8bc80f28177f1951611c1d43286ffMathias Agopian                    if (filtering) layer->setFiltering(false);
2276b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                }
2277bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian            }
227874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        }
227974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
228074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // check for errors and return screen capture
228174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        if (glGetError() != GL_NO_ERROR) {
228274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // error while rendering
228374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            result = INVALID_OPERATION;
228474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        } else {
228574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // allocate shared memory large enough to hold the
228674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // screen capture
228774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            sp<MemoryHeapBase> base(
228874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    new MemoryHeapBase(size, 0, "screen-capture") );
228974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            void* const ptr = base->getBase();
229074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            if (ptr) {
229174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                // capture the screen with glReadPixels()
2292fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian                ScopedTrace _t(ATRACE_TAG, "glReadPixels");
229374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                glReadPixels(0, 0, sw, sh, GL_RGBA, GL_UNSIGNED_BYTE, ptr);
229474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                if (glGetError() == GL_NO_ERROR) {
229574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *heap = base;
229674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *w = sw;
229774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *h = sh;
229874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *f = PIXEL_FORMAT_RGBA_8888;
229974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    result = NO_ERROR;
230074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                }
230174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            } else {
230274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                result = NO_MEMORY;
230374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            }
230474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        }
230574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glViewport(0, 0, hw_w, hw_h);
230674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_PROJECTION);
230774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glPopMatrix();
230874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_MODELVIEW);
230974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    } else {
231074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        result = BAD_VALUE;
231174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    }
231274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
231374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // release FBO resources
231474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
231574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glDeleteRenderbuffersOES(1, &tname);
231674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glDeleteFramebuffersOES(1, &name);
2317e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian
23184297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->compositionComplete();
2319e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian
2320ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian//    ALOGD("screenshot: result = %s", result<0 ? strerror(result) : "OK");
2321c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
232274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    return result;
232374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian}
232474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
232574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
23261b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopianstatus_t SurfaceFlinger::captureScreen(DisplayID dpy,
23271b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        sp<IMemoryHeap>* heap,
232874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t* width, uint32_t* height, PixelFormat* format,
2329bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t sw, uint32_t sh,
2330bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ, uint32_t maxLayerZ)
23311b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian{
23321b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    // only one display supported for now
233399ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten    if (CC_UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
23341b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        return BAD_VALUE;
23351b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
23361b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
23371b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        return INVALID_OPERATION;
23381b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
23391b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    class MessageCaptureScreen : public MessageBase {
23401b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        SurfaceFlinger* flinger;
23411b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        DisplayID dpy;
23421b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        sp<IMemoryHeap>* heap;
23431b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        uint32_t* w;
23441b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        uint32_t* h;
23451b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        PixelFormat* f;
234674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t sw;
234774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t sh;
2348bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ;
2349bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t maxLayerZ;
23501b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        status_t result;
23511b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    public:
23521b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        MessageCaptureScreen(SurfaceFlinger* flinger, DisplayID dpy,
235374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                sp<IMemoryHeap>* heap, uint32_t* w, uint32_t* h, PixelFormat* f,
2354bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                uint32_t sw, uint32_t sh,
2355bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                uint32_t minLayerZ, uint32_t maxLayerZ)
23561b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            : flinger(flinger), dpy(dpy),
2357bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              heap(heap), w(w), h(h), f(f), sw(sw), sh(sh),
2358bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              minLayerZ(minLayerZ), maxLayerZ(maxLayerZ),
2359bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              result(PERMISSION_DENIED)
23601b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
23611b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
23621b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        status_t getResult() const {
23631b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            return result;
23641b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
23651b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        virtual bool handler() {
23661b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
236774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            result = flinger->captureScreenImplLocked(dpy,
2368bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                    heap, w, h, f, sw, sh, minLayerZ, maxLayerZ);
23691b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            return true;
23701b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
23711b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    };
23721b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
23731b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    sp<MessageBase> msg = new MessageCaptureScreen(this,
2374bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian            dpy, heap, width, height, format, sw, sh, minLayerZ, maxLayerZ);
23751b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    status_t res = postMessageSync(msg);
23761b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    if (res == NO_ERROR) {
23771b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        res = static_cast<MessageCaptureScreen*>( msg.get() )->getResult();
23781b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    }
23791b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    return res;
23801b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian}
23811b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
23821b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// ---------------------------------------------------------------------------
23831b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
2384921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::LayerVector::LayerVector() {
2385921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
2386921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
2387921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::LayerVector::LayerVector(const LayerVector& rhs)
2388921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    : SortedVector<sp<LayerBase> >(rhs) {
2389921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
2390921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
2391921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianint SurfaceFlinger::LayerVector::do_compare(const void* lhs,
2392921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    const void* rhs) const
2393edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2394be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    // sort layers per layer-stack, then by z-order and finally by sequence
2395921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    const sp<LayerBase>& l(*reinterpret_cast<const sp<LayerBase>*>(lhs));
2396921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    const sp<LayerBase>& r(*reinterpret_cast<const sp<LayerBase>*>(rhs));
2397be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian
2398be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    uint32_t ls = l->currentState().layerStack;
2399be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    uint32_t rs = r->currentState().layerStack;
2400be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    if (ls != rs)
2401be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian        return ls - rs;
2402be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian
2403921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    uint32_t lz = l->currentState().z;
2404921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    uint32_t rz = r->currentState().z;
2405be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    if (lz != rz)
2406be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian        return lz - rz;
2407be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian
2408be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    return l->sequence - r->sequence;
2409921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
2410921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
2411921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian// ---------------------------------------------------------------------------
2412921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
2413e57f292595bec48f65c8088b00ff6beea01217e9Mathias AgopianSurfaceFlinger::DisplayDeviceState::DisplayDeviceState() : id(-1) {
2414e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
2415e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
2416e57f292595bec48f65c8088b00ff6beea01217e9Mathias AgopianSurfaceFlinger::DisplayDeviceState::DisplayDeviceState(int32_t id)
2417e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    : id(id), layerStack(0), orientation(0) {
2418b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
24197303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
2420b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// ---------------------------------------------------------------------------
242196f0819f81293076e652792794a961543e6750d7Mathias Agopian
24229a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::GraphicBufferAlloc() {}
24239a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
24249a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::~GraphicBufferAlloc() {}
24259a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
24269a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h,
2427d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        PixelFormat format, uint32_t usage, status_t* error) {
24289a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(w, h, format, usage));
24299a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    status_t err = graphicBuffer->initCheck();
2430d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian    *error = err;
2431a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (err != 0 || graphicBuffer->handle == 0) {
2432d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        if (err == NO_MEMORY) {
2433d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian            GraphicBuffer::dumpAllocationsToSystemLog();
2434d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        }
2435e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE("GraphicBufferAlloc::createGraphicBuffer(w=%d, h=%d) "
2436a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian             "failed (%s), handle=%p",
2437a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                w, h, strerror(-err), graphicBuffer->handle);
24389a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis        return 0;
24399a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    }
24409a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    return graphicBuffer;
24419a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis}
24429a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
24439a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis// ---------------------------------------------------------------------------
24449a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
2445edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
2446