SurfaceFlinger.cpp revision e57f292595bec48f65c8088b00ff6beea01217e9
1edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/*
2edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
3edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
4edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * you may not use this file except in compliance with the License.
6edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * You may obtain a copy of the License at
7edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
8edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
10edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * See the License for the specific language governing permissions and
14edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * limitations under the License.
15edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */
16edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
171c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#define ATRACE_TAG ATRACE_TAG_GRAPHICS
181c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
19edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdint.h>
20921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <sys/types.h>
21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <errno.h>
22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <math.h>
23921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
24921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <EGL/egl.h>
25921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <GLES/gl.h>
26edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
27edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/log.h>
28edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/properties.h>
29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
30c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IPCThreadState.h>
31c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IServiceManager.h>
327303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian#include <binder/MemoryHeapBase.h>
3399b49840d309727678b77403d6cc9f920111623fMathias Agopian#include <binder/PermissionCache.h>
347303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
35c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian#include <ui/DisplayInfo.h>
36c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian
37921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <gui/BitTube.h>
381a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <gui/BufferQueue.h>
391a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <gui/IDisplayEventConnection.h>
40921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <gui/SurfaceTextureClient.h>
41921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
42921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <ui/GraphicBufferAllocator.h>
43921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <ui/PixelFormat.h>
44d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String8.h>
46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String16.h>
47edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/StopWatch.h>
481c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#include <utils/Trace.h>
49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
50921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <private/android_filesystem_config.h>
51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h"
5390ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include "DdmConnection.h"
540f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian#include "DisplayDevice.h"
55db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian#include "Client.h"
56d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian#include "EventThread.h"
571f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian#include "GLExtensions.h"
58edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h"
59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerDim.h"
60118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian#include "LayerScreenshot.h"
61edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h"
62edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
63a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#include "DisplayHardware/FramebufferSurface.h"
64a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian#include "DisplayHardware/HWComposer.h"
65edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
66a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
67bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian#define EGL_VERSION_HW_ANDROID  0x3143
68bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DISPLAY_COUNT       1
70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
73edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
7499b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sHardwareTest("android.permission.HARDWARE_TEST");
7599b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER");
7699b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER");
7799b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sDump("android.permission.DUMP");
7899b49840d309727678b77403d6cc9f920111623fMathias Agopian
7999b49840d309727678b77403d6cc9f920111623fMathias Agopian// ---------------------------------------------------------------------------
8099b49840d309727678b77403d6cc9f920111623fMathias Agopian
81edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::SurfaceFlinger()
82edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    :   BnSurfaceComposer(), Thread(false),
83edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mTransactionFlags(0),
8428378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        mTransationPending(false),
85076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved(false),
8652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        mRepaintEverything(0),
87edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mBootTime(systemTime()),
88edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mVisibleRegionsDirty(false),
89a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        mHwWorkListDirty(false),
90edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDebugRegion(0),
918afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian        mDebugDDMS(0),
9273d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian        mDebugDisableHWC(0),
93a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian        mDebugDisableTransformHint(0),
949795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInSwapBuffers(0),
959795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastSwapBufferTime(0),
969795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInTransaction(0),
979795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastTransactionTime(0),
983330b203039dea366d4981db1408a460134b2d2cMathias Agopian        mBootFinished(false),
993094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        mExternalDisplaySurface(EGL_NO_SURFACE)
100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
101a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI("SurfaceFlinger is starting");
102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // debugging stuff...
104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char value[PROPERTY_VALUE_MAX];
1058afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    property_get("debug.sf.showupdates", value, "0");
107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDebugRegion = atoi(value);
1088afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
1098afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    property_get("debug.sf.ddms", value, "0");
1108afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    mDebugDDMS = atoi(value);
1118afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    if (mDebugDDMS) {
1128afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian        DdmConnection::start(getServiceName());
1138afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    }
1148afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
115c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    ALOGI_IF(mDebugRegion, "showupdates enabled");
116c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    ALOGI_IF(mDebugDDMS, "DDMS debugging enabled");
117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
11999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::onFirstRef()
12099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
12199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.init(this);
12299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
12399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY);
12499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
12599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // Wait for the main thread to be done with its initialization
12699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mReadyToRunBarrier.wait();
12799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
12899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
12999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::~SurfaceFlinger()
131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
132a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
133a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
134a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglTerminate(display);
135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
13799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::binderDied(const wp<IBinder>& who)
13899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
13999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // the window manager died on us. prepare its eulogy.
14099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
14199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // reset screen orientation
14299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    Vector<ComposerState> state;
1438b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian    Vector<DisplayState> displays;
1448b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian    DisplayState d;
1453165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian    d.orientation = DisplayState::eOrientationDefault;
1468b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian    displays.add(d);
1478b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian    setTransactionState(state, displays, 0);
14899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
14999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // restart the boot-animation
150a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    startBootAnim();
15199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
15299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
1537e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopiansp<ISurfaceComposerClient> SurfaceFlinger::createConnection()
154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
15596f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<ISurfaceComposerClient> bclient;
15696f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<Client> client(new Client(this));
15796f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = client->initCheck();
15896f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR) {
15996f0819f81293076e652792794a961543e6750d7Mathias Agopian        bclient = client;
160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return bclient;
162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
164e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopiansp<IBinder> SurfaceFlinger::createDisplay()
165e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{
166e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    class DisplayToken : public BBinder {
167e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        sp<SurfaceFlinger> flinger;
168e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        virtual ~DisplayToken() {
169e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             // no more references, this display must be terminated
170e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             Mutex::Autolock _l(flinger->mStateLock);
171e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             flinger->mCurrentState.displays.removeItem(this);
172e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             flinger->setTransactionFlags(eDisplayTransactionNeeded);
173e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian         }
174e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian     public:
175e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        DisplayToken(const sp<SurfaceFlinger>& flinger)
176e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            : flinger(flinger) {
177e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
178e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    };
179e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
180e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    sp<BBinder> token = new DisplayToken(this);
181e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
182e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    Mutex::Autolock _l(mStateLock);
183e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    DisplayDeviceState info(intptr_t(token.get())); // FIXME: we shouldn't use the address for the id
184e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    mCurrentState.displays.add(token, info);
185e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
186e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return token;
187e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
188e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
189e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopiansp<IBinder> SurfaceFlinger::getBuiltInDisplay(int32_t id) {
190e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    if (uint32_t(id) >= DisplayDevice::DISPLAY_ID_COUNT) {
191e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        ALOGE("getDefaultDisplay: id=%d is not a valid default display id", id);
192e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        return NULL;
193e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
194e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return mDefaultDisplays[id];
195e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
196e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
1979a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc()
1989a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis{
1999a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc());
2009a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    return gba;
2019a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis}
202b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
203edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::bootFinished()
204edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
205edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t now = systemTime();
206edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t duration = now - mBootTime;
207a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
2083330b203039dea366d4981db1408a460134b2d2cMathias Agopian    mBootFinished = true;
2091f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
2101f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // wait patiently for the window manager death
2111f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    const String16 name("window");
2121f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    sp<IBinder> window(defaultServiceManager()->getService(name));
2131f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    if (window != 0) {
214921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        window->linkToDeath(static_cast<IBinder::DeathRecipient*>(this));
2151f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    }
2161f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
2171f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // stop boot animation
218a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // formerly we would just kill the process, but we now ask it to exit so it
219a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // can choose where to stop the animation.
220a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("service.bootanim.exit", "1");
221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
223921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianvoid SurfaceFlinger::deleteTextureAsync(GLuint texture) {
224921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    class MessageDestroyGLTexture : public MessageBase {
225921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        GLuint texture;
226921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    public:
227921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        MessageDestroyGLTexture(GLuint texture)
228921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian            : texture(texture) {
229921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        }
230921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        virtual bool handler() {
231921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian            glDeleteTextures(1, &texture);
232921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian            return true;
233921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        }
234921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    };
235921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    postMessageAsync(new MessageDestroyGLTexture(texture));
236921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
237921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
238a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianstatus_t SurfaceFlinger::selectConfigForPixelFormat(
239a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        EGLDisplay dpy,
240a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        EGLint const* attrs,
241a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        PixelFormat format,
242a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        EGLConfig* outConfig)
243a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian{
244a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLConfig config = NULL;
245a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLint numConfigs = -1, n=0;
246a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglGetConfigs(dpy, NULL, 0, &numConfigs);
247a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLConfig* const configs = new EGLConfig[numConfigs];
248a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglChooseConfig(dpy, attrs, configs, numConfigs, &n);
249a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    for (int i=0 ; i<n ; i++) {
250a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        EGLint nativeVisualId = 0;
251a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        eglGetConfigAttrib(dpy, configs[i], EGL_NATIVE_VISUAL_ID, &nativeVisualId);
252a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        if (nativeVisualId>0 && format == nativeVisualId) {
253a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            *outConfig = configs[i];
254a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            delete [] configs;
255a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            return NO_ERROR;
256a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        }
257a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    }
258a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    delete [] configs;
259a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    return NAME_NOT_FOUND;
260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
262a49126087b4494f4ef50873f3a3f6727265f6621Mathias AgopianEGLConfig SurfaceFlinger::selectEGLConfig(EGLDisplay display, EGLint nativeVisualId) {
263a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // select our EGLConfig. It must support EGL_RECORDABLE_ANDROID if
264a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // it is to be used with WIFI displays
265a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLConfig config;
266a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLint dummy;
267a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    status_t err;
268a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLint attribs[] = {
269a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            EGL_SURFACE_TYPE,           EGL_WINDOW_BIT,
270a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            EGL_RECORDABLE_ANDROID,     EGL_TRUE,
271a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            EGL_NONE
272a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    };
273a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    err = selectConfigForPixelFormat(display, attribs, nativeVisualId, &config);
274a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    if (err) {
275a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        // maybe we failed because of EGL_RECORDABLE_ANDROID
276a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        ALOGW("couldn't find an EGLConfig with EGL_RECORDABLE_ANDROID");
277a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        attribs[2] = EGL_NONE;
278a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        err = selectConfigForPixelFormat(display, attribs, nativeVisualId, &config);
279a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    }
280a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGE_IF(err, "couldn't find an EGLConfig matching the screen format");
281a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    if (eglGetConfigAttrib(display, config, EGL_CONFIG_CAVEAT, &dummy) == EGL_TRUE) {
282a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        ALOGW_IF(dummy == EGL_SLOW_CONFIG, "EGL_SLOW_CONFIG selected!");
283a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    }
284a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    return config;
285a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
286edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
287a49126087b4494f4ef50873f3a3f6727265f6621Mathias AgopianEGLContext SurfaceFlinger::createGLContext(EGLDisplay display, EGLConfig config) {
288a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // Also create our EGLContext
289a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLint contextAttributes[] = {
290a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#ifdef EGL_IMG_context_priority
291a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#ifdef HAS_CONTEXT_PRIORITY
292a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#warning "using EGL_IMG_context_priority"
293a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_HIGH_IMG,
294a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#endif
295a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#endif
296a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            EGL_NONE, EGL_NONE
297a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    };
298a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLContext ctxt = eglCreateContext(display, config, NULL, contextAttributes);
299a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGE_IF(ctxt==EGL_NO_CONTEXT, "EGLContext creation failed");
300a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    return ctxt;
301a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
302edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
303a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianvoid SurfaceFlinger::initializeGL(EGLDisplay display, EGLSurface surface) {
304a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLBoolean result = eglMakeCurrent(display, surface, surface, mEGLContext);
305a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    if (!result) {
306a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        ALOGE("Couldn't create a working GLES context. check logs. exiting...");
307a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        exit(0);
308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
310a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    GLExtensions& extensions(GLExtensions::getInstance());
311a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    extensions.initWithGLStrings(
312a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            glGetString(GL_VENDOR),
313a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            glGetString(GL_RENDERER),
314a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            glGetString(GL_VERSION),
315a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            glGetString(GL_EXTENSIONS),
316a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            eglQueryString(display, EGL_VENDOR),
317a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            eglQueryString(display, EGL_VERSION),
318a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            eglQueryString(display, EGL_EXTENSIONS));
3198b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
320a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLint w, h;
321a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglQuerySurface(display, surface, EGL_WIDTH,  &w);
322a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglQuerySurface(display, surface, EGL_HEIGHT, &h);
3238b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
324a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
325a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    glGetIntegerv(GL_MAX_VIEWPORT_DIMS, mMaxViewportDims);
3267303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
327edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
3288b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber    glPixelStorei(GL_PACK_ALIGNMENT, 4);
329edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glEnableClientState(GL_VERTEX_ARRAY);
330edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glShadeModel(GL_FLAT);
331edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_DITHER);
332edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_CULL_FACE);
333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
334a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    struct pack565 {
335a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        inline uint16_t operator() (int r, int g, int b) const {
336a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            return (r<<11)|(g<<5)|b;
337a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        }
338a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    } pack565;
339a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
3409575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    const uint16_t protTexData[] = { pack565(0x03, 0x03, 0x03) };
3419575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glGenTextures(1, &mProtectedTexName);
3429575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glBindTexture(GL_TEXTURE_2D, mProtectedTexName);
3439575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3449575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3459575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
3469575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
3479575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0,
3489575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis            GL_RGB, GL_UNSIGNED_SHORT_5_6_5, protTexData);
349edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
350edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glViewport(0, 0, w, h);
351edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glMatrixMode(GL_PROJECTION);
352edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glLoadIdentity();
353ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    // put the origin in the left-bottom corner
354ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    glOrthof(0, w, 0, h, 0, 1); // l=0, r=w ; b=0, t=h
355edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
356a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // print some debugging info
357a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLint r,g,b,a;
358a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglGetConfigAttrib(display, mEGLConfig, EGL_RED_SIZE,   &r);
359a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglGetConfigAttrib(display, mEGLConfig, EGL_GREEN_SIZE, &g);
360a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglGetConfigAttrib(display, mEGLConfig, EGL_BLUE_SIZE,  &b);
361a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglGetConfigAttrib(display, mEGLConfig, EGL_ALPHA_SIZE, &a);
362a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("EGL informations:");
363a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("vendor    : %s", extensions.getEglVendor());
364a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("version   : %s", extensions.getEglVersion());
365a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("extensions: %s", extensions.getEglExtension());
366a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("Client API: %s", eglQueryString(display, EGL_CLIENT_APIS)?:"Not Supported");
367a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("EGLSurface: %d-%d-%d-%d, config=%p", r, g, b, a, mEGLConfig);
368a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("OpenGL ES informations:");
369a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("vendor    : %s", extensions.getVendor());
370a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("renderer  : %s", extensions.getRenderer());
371a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("version   : %s", extensions.getVersion());
372a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("extensions: %s", extensions.getExtension());
373a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("GL_MAX_TEXTURE_SIZE = %d", mMaxTextureSize);
374a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("GL_MAX_VIEWPORT_DIMS = %d x %d", mMaxViewportDims[0], mMaxViewportDims[1]);
375a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
376a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
377a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianstatus_t SurfaceFlinger::readyToRun()
378a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian{
379a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI(  "SurfaceFlinger's main thread ready to run. "
380a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            "Initializing graphics H/W...");
381a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
382a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // initialize EGL
38334a09ba1efd706323a15633da5044b352988eb5fJesse Hall    mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
38434a09ba1efd706323a15633da5044b352988eb5fJesse Hall    eglInitialize(mEGLDisplay, NULL, NULL);
385a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
386a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // Initialize the main display
387a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // create native window to main display
3881a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    sp<FramebufferSurface> fbs = FramebufferSurface::create();
3891a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    if (fbs == NULL) {
390a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        ALOGE("Display subsystem failed to initialize. check logs. exiting...");
391a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        exit(0);
392a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    }
393a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
394e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    sp<SurfaceTextureClient> stc(new SurfaceTextureClient(
395e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            static_cast<sp<ISurfaceTexture> >(fbs->getBufferQueue())));
3961a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
397a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // initialize the config and context
398a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    int format;
3991a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    ANativeWindow* const anw = stc.get();
4001a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    anw->query(anw, NATIVE_WINDOW_FORMAT, &format);
40134a09ba1efd706323a15633da5044b352988eb5fJesse Hall    mEGLConfig  = selectEGLConfig(mEGLDisplay, format);
40234a09ba1efd706323a15633da5044b352988eb5fJesse Hall    mEGLContext = createGLContext(mEGLDisplay, mEGLConfig);
403a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
404a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // initialize our main display hardware
405e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
406e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    for (size_t i=0 ; i<DisplayDevice::DISPLAY_ID_COUNT ; i++) {
407e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        mDefaultDisplays[i] = new BBinder();
408e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        mCurrentState.displays.add(mDefaultDisplays[i], DisplayDeviceState(i));
409e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
410e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    sp<DisplayDevice> hw = new DisplayDevice(this,
411e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            DisplayDevice::DISPLAY_ID_MAIN, anw, fbs, mEGLConfig);
412e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    mDisplays.add(hw->getDisplayId(), hw);
413a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
414a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    //  initialize OpenGL ES
4154297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    EGLSurface surface = hw->getEGLSurface();
41634a09ba1efd706323a15633da5044b352988eb5fJesse Hall    initializeGL(mEGLDisplay, surface);
417d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
418028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian    // start the EventThread
419028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian    mEventThread = new EventThread(this);
420028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian    mEventQueue.setEventThread(mEventThread);
421028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian
4228630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    // initialize the H/W composer
423888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian    mHwc = new HWComposer(this, *static_cast<HWComposer::EventHandler *>(this));
42492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian
42592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    // initialize our drawing state
42692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    mDrawingState = mCurrentState;
4278630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
428a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // We're now ready to accept clients...
429d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian    mReadyToRunBarrier.open();
430d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
431a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    // start boot animation
432a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    startBootAnim();
4338b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
434edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
435edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
436edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
437a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopianvoid SurfaceFlinger::startBootAnim() {
438a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // start boot animation
439a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("service.bootanim.exit", "0");
440a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("ctl.start", "bootanim");
441a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian}
442a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian
443a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianuint32_t SurfaceFlinger::getMaxTextureSize() const {
444a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    return mMaxTextureSize;
445a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
446a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
447a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianuint32_t SurfaceFlinger::getMaxViewportDims() const {
448a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    return mMaxViewportDims[0] < mMaxViewportDims[1] ?
449a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            mMaxViewportDims[0] : mMaxViewportDims[1];
450a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
451a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
452edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
453d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
454582270d69db94286a248bd829f1ae6f910d45124Jamie Gennisbool SurfaceFlinger::authenticateSurfaceTexture(
455582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis        const sp<ISurfaceTexture>& surfaceTexture) const {
456134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    Mutex::Autolock _l(mStateLock);
457582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis    sp<IBinder> surfaceTextureBinder(surfaceTexture->asBinder());
458134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
459134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // Check the visible layer list for the ISurface
460134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
461134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    size_t count = currentLayers.size();
462134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    for (size_t i=0 ; i<count ; i++) {
463134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        const sp<LayerBase>& layer(currentLayers[i]);
464134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        sp<LayerBaseClient> lbc(layer->getLayerBaseClient());
465582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis        if (lbc != NULL) {
466582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder();
467582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            if (lbcBinder == surfaceTextureBinder) {
468582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis                return true;
469582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            }
470134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        }
471134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    }
472134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
473134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // Check the layers in the purgatory.  This check is here so that if a
474582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis    // SurfaceTexture gets destroyed before all the clients are done using it,
475582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis    // the error will not be reported as "surface XYZ is not authenticated", but
476134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // will instead fail later on when the client tries to use the surface,
477134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // which should be reported as "surface XYZ returned an -ENODEV".  The
478134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // purgatorized layers are no less authentic than the visible ones, so this
479134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // should not cause any harm.
480134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    size_t purgatorySize =  mLayerPurgatory.size();
481134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    for (size_t i=0 ; i<purgatorySize ; i++) {
482134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
483134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        sp<LayerBaseClient> lbc(layer->getLayerBaseClient());
484582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis        if (lbc != NULL) {
485582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder();
486582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            if (lbcBinder == surfaceTextureBinder) {
487582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis                return true;
488582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            }
489134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        }
490134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    }
491134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
492134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    return false;
493134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis}
494134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
495c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopianstatus_t SurfaceFlinger::getDisplayInfo(DisplayID dpy, DisplayInfo* info) {
4961e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian    // TODO: this is here only for compatibility -- should go away eventually.
4971e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian    if (uint32_t(dpy) >= 1) {
498c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian        return BAD_INDEX;
499c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian    }
5004297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    sp<const DisplayDevice> hw(getDefaultDisplayDevice());
5014297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    info->w = hw->getWidth();
5024297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    info->h = hw->getHeight();
5034297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    info->xdpi = hw->getDpiX();
5044297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    info->ydpi = hw->getDpiY();
505888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian    info->fps = float(1e9 / getHwComposer().getRefreshPeriod());
5064297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    info->density = hw->getDensity();
5074297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    info->orientation = hw->getOrientation();
508888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian    // TODO: this needs to go away (currently needed only by webkit)
5094297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    getPixelFormatInfo(hw->getFormat(), &info->pixelFormatInfo);
510888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian    return NO_ERROR;
511c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian}
512c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian
513d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian// ----------------------------------------------------------------------------
514d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
515d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopiansp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection() {
5168aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian    return mEventThread->createEventConnection();
517bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian}
518bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
5193094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopianvoid SurfaceFlinger::connectDisplay(const sp<ISurfaceTexture> display) {
5203094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    EGLSurface result = EGL_NO_SURFACE;
5213094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    EGLSurface old_surface = EGL_NO_SURFACE;
5223094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    sp<SurfaceTextureClient> stc;
5233094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
5243094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    if (display != NULL) {
5253094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        stc = new SurfaceTextureClient(display);
526d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        result = eglCreateWindowSurface(mEGLDisplay,
527a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian                mEGLConfig, (EGLNativeWindowType)stc.get(), NULL);
5283094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        ALOGE_IF(result == EGL_NO_SURFACE,
5293094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                "eglCreateWindowSurface failed (ISurfaceTexture=%p)",
5303094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                display.get());
5313094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    }
5323094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
5333094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    { // scope for the lock
5343094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        Mutex::Autolock _l(mStateLock);
5353094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        old_surface = mExternalDisplaySurface;
5363094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        mExternalDisplayNativeWindow = stc;
5373094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        mExternalDisplaySurface = result;
5383094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        ALOGD("mExternalDisplaySurface = %p", result);
5393094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    }
5403094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
5413094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    if (old_surface != EGL_NO_SURFACE) {
5423094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        // Note: EGL allows to destroy an object while its current
5433094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        // it will fail to become current next time though.
544d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        eglDestroySurface(mEGLDisplay, old_surface);
5453094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    }
5463094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian}
5473094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
5483094df359d1e6e2ae8ca4e935cc093f563804c96Mathias AgopianEGLSurface SurfaceFlinger::getExternalDisplaySurface() const {
5493094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    Mutex::Autolock _l(mStateLock);
5503094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    return mExternalDisplaySurface;
5513094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian}
5523094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
553edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
55499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
55599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::waitForEvent() {
55699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.waitMessage();
55799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
55899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
55999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalTransaction() {
56099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.invalidate();
56199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
56299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
56399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalLayerUpdate() {
56499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.invalidate();
56599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
56699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
56799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalRefresh() {
56899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.refresh();
56999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
57099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
57199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg,
57299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        nsecs_t reltime, uint32_t flags) {
57399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return mEventQueue.postMessage(msg, reltime);
57499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
57599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
57699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,
57799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        nsecs_t reltime, uint32_t flags) {
57899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    status_t res = mEventQueue.postMessage(msg, reltime);
57999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    if (res == NO_ERROR) {
58099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        msg->wait();
58199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    }
58299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return res;
58399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
584edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5854fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianbool SurfaceFlinger::threadLoop() {
586edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    waitForEvent();
58799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return true;
58899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
589edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5908630320433bd15aca239522e54e711ef6372ab07Mathias Agopianvoid SurfaceFlinger::onVSyncReceived(int dpy, nsecs_t timestamp) {
5918630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    mEventThread->onVSyncReceived(dpy, timestamp);
5928630320433bd15aca239522e54e711ef6372ab07Mathias Agopian}
5938630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
5948630320433bd15aca239522e54e711ef6372ab07Mathias Agopianvoid SurfaceFlinger::eventControl(int event, int enabled) {
5958630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    getHwComposer().eventControl(event, enabled);
5968630320433bd15aca239522e54e711ef6372ab07Mathias Agopian}
5978630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
5984fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::onMessageReceived(int32_t what) {
5991c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
60099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    switch (what) {
6014fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    case MessageQueue::INVALIDATE:
6024fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        handleMessageTransaction();
6034fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        handleMessageInvalidate();
6044fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        signalRefresh();
6054fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        break;
6064fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    case MessageQueue::REFRESH:
6074fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        handleMessageRefresh();
6084fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        break;
6094fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
6104fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
611edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
6124fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageTransaction() {
613e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    uint32_t transactionFlags = peekTransactionFlags(eTransactionMask);
6144fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    if (transactionFlags) {
61587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        handleTransaction(transactionFlags);
6164fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
6174fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
618edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
6194fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageInvalidate() {
62087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    handlePageFlip();
6214fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
6223a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian
6234fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageRefresh() {
6244fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    handleRefresh();
625a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
62652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    if (CC_UNLIKELY(mVisibleRegionsDirty)) {
62787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        mVisibleRegionsDirty = false;
62887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        invalidateHwcGeometry();
6293b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
6303b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        /*
6313b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian         *  rebuild the visible layer list per screen
6323b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian         */
6333b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
63487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
63592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
6364297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            const sp<DisplayDevice>& hw(mDisplays[dpy]);
63787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            Region opaqueRegion;
63887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            Region dirtyRegion;
63987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            computeVisibleRegions(currentLayers,
6404297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                    hw->getLayerStack(), dirtyRegion, opaqueRegion);
6414297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->dirtyRegion.orSelf(dirtyRegion);
64287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
64387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            Vector< sp<LayerBase> > layersSortedByZ;
64487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            const size_t count = currentLayers.size();
64587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            for (size_t i=0 ; i<count ; i++) {
64687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian                const Layer::State& s(currentLayers[i]->drawingState());
6474297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                if (s.layerStack == hw->getLayerStack()) {
64887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian                    if (!currentLayers[i]->visibleRegion.isEmpty()) {
64987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian                        layersSortedByZ.add(currentLayers[i]);
65087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian                    }
65187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian                }
6523b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian            }
6534297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->setVisibleLayersSortedByZ(layersSortedByZ);
6544297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->undefinedRegion.set(hw->getBounds());
6554297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->undefinedRegion.subtractSelf(hw->getTransform().transform(opaqueRegion));
6563b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        }
6573b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
6583b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
65952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    HWComposer& hwc(getHwComposer());
66052bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    if (hwc.initCheck() == NO_ERROR) {
66152bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        // build the h/w work list
66252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        const bool workListsDirty = mHwWorkListDirty;
66352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        mHwWorkListDirty = false;
66492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
6654297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            sp<const DisplayDevice> hw(mDisplays[dpy]);
6664297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            const Vector< sp<LayerBase> >& currentLayers(hw->getVisibleLayersSortedByZ());
66752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            const size_t count = currentLayers.size();
668303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian
6691e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian            const int32_t id = hw->getDisplayId();
6701e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian            if (hwc.createWorkList(id, count) >= 0) {
6711e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                HWComposer::LayerListIterator cur = hwc.begin(id);
6721e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                const HWComposer::LayerListIterator end = hwc.end(id);
6731e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
6741e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                    const sp<LayerBase>& layer(currentLayers[i]);
6751e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian
6761e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                    if (CC_UNLIKELY(workListsDirty)) {
6771e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                        layer->setGeometry(hw, *cur);
6781e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                        if (mDebugDisableHWC || mDebugRegion) {
6791e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                            cur->setSkip(true);
6801e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                        }
68152bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian                    }
68252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian
6831e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                    /*
6841e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                     * update the per-frame h/w composer data for each layer
6851e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                     * and build the transparent region of the FB
6861e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                     */
6871e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                    layer->setPerFrameData(hw, *cur);
6881e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                }
68952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            }
69087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        }
69152bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        status_t err = hwc.prepare();
69252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
69352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    }
69452bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian
69552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    const bool repaintEverything = android_atomic_and(0, &mRepaintEverything);
69692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
6974297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
698303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian
69987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        // transform the dirty region into this screen's coordinate space
7004297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const Transform& planeTransform(hw->getTransform());
70187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        Region dirtyRegion;
70287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        if (repaintEverything) {
7034297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            dirtyRegion.set(hw->bounds());
70452bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        } else {
7054297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            dirtyRegion = planeTransform.transform(hw->dirtyRegion);
7064297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            dirtyRegion.andSelf(hw->bounds());
70787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        }
7084297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        hw->dirtyRegion.clear();
709b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian
71052bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        if (!dirtyRegion.isEmpty()) {
7114297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            if (hw->canDraw()) {
71252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian                // repaint the framebuffer (if needed)
71352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian                handleRepaint(hw, dirtyRegion);
71452bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            }
71587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        }
71652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        // inform the h/w that we're done compositing
7174297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        hw->compositionComplete();
7184fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
7193094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
72052bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    postFramebuffer();
72187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
72252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian
72352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian#if 1
7244fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    // render to the external display if we have one
7254fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    EGLSurface externalDisplaySurface = getExternalDisplaySurface();
7264fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    if (externalDisplaySurface != EGL_NO_SURFACE) {
7274fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        EGLSurface cur = eglGetCurrentSurface(EGL_DRAW);
7284fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        EGLBoolean success = eglMakeCurrent(eglGetCurrentDisplay(),
7294fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                externalDisplaySurface, externalDisplaySurface,
7304fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                eglGetCurrentContext());
7314fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
7324fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        ALOGE_IF(!success, "eglMakeCurrent -> external failed");
7334fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
7344fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        if (success) {
7354fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            // redraw the screen entirely...
7364fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            glDisable(GL_TEXTURE_EXTERNAL_OES);
7374fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            glDisable(GL_TEXTURE_2D);
7384fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            glClearColor(0,0,0,1);
7394fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            glClear(GL_COLOR_BUFFER_BIT);
7404fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            glMatrixMode(GL_MODELVIEW);
7414fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            glLoadIdentity();
7423b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
7434297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            const sp<DisplayDevice>& hw(getDisplayDevice(0));
7444297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            const Vector< sp<LayerBase> >& layers( hw->getVisibleLayersSortedByZ() );
7454fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const size_t count = layers.size();
7464fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            for (size_t i=0 ; i<count ; ++i) {
7474fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                const sp<LayerBase>& layer(layers[i]);
748fcb239d3dac8bc80f28177f1951611c1d43286ffMathias Agopian                layer->draw(hw);
7494fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            }
7503094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
7514fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            success = eglSwapBuffers(eglGetCurrentDisplay(), externalDisplaySurface);
7524fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            ALOGE_IF(!success, "external display eglSwapBuffers failed");
7533094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
7544297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->compositionComplete();
7554fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        }
7563094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
7574fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        success = eglMakeCurrent(eglGetCurrentDisplay(),
7584fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                cur, cur, eglGetCurrentContext());
7594fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
7604fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        ALOGE_IF(!success, "eglMakeCurrent -> internal failed");
761edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
76287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian#endif
7634fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
764edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
765edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
766edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer()
767edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
768841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
769b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian
770a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    const nsecs_t now = systemTime();
771a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = now;
772c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall
77352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    HWComposer& hwc(getHwComposer());
77452bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian
77592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
7764297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
77752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        if (hwc.initCheck() == NO_ERROR) {
7784297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            const Vector< sp<LayerBase> >& currentLayers(hw->getVisibleLayersSortedByZ());
77952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            const size_t count = currentLayers.size();
7801e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian            const int32_t id = hw->getDisplayId();
7811e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian            HWComposer::LayerListIterator cur = hwc.begin(id);
7821e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian            const HWComposer::LayerListIterator end = hwc.end(id);
78352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
78452bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian                const sp<LayerBase>& layer(currentLayers[i]);
785d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian                layer->setAcquireFence(hw, *cur);
786c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall            }
787c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall        }
7884297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        hw->flip(hw->swapRegion);
7894297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        hw->swapRegion.clear();
790c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall    }
791c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall
792ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall    if (hwc.initCheck() == NO_ERROR) {
79352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        // FIXME: eventually commit() won't take arguments
7944297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        hwc.commit(mEGLDisplay, getDefaultDisplayDevice()->getEGLSurface());
79552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    }
79652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian
79792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
7984297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        sp<const DisplayDevice> hw(mDisplays[dpy]);
7994297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const Vector< sp<LayerBase> >& currentLayers(hw->getVisibleLayersSortedByZ());
80052bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        const size_t count = currentLayers.size();
80152bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        if (hwc.initCheck() == NO_ERROR) {
8021e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian            int32_t id = hw->getDisplayId();
8031e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian            HWComposer::LayerListIterator cur = hwc.begin(id);
8041e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian            const HWComposer::LayerListIterator end = hwc.end(id);
80552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            for (size_t i = 0; cur != end && i < count; ++i, ++cur) {
806d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian                currentLayers[i]->onLayerDisplayed(hw, &*cur);
80752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            }
80852bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        } else {
8094297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            eglSwapBuffers(mEGLDisplay, hw->getEGLSurface());
81052bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            for (size_t i = 0; i < count; i++) {
811d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian                currentLayers[i]->onLayerDisplayed(hw, NULL);
81252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            }
813ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall        }
81452bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian
81552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        // FIXME: we need to call eglSwapBuffers() on displays that have GL composition
816e8696a40e09b24b634214684d18526187b316a2fJamie Gennis    }
817e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
818a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mLastSwapBufferTime = systemTime() - now;
819a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = 0;
820edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
821edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
82287baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
823edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
824841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
825841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
826ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    Mutex::Autolock _l(mStateLock);
827ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    const nsecs_t now = systemTime();
828ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = now;
829ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
830ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // Here we're guaranteed that some transaction flags are set
831ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // so we can call handleTransactionLocked() unconditionally.
832ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // We call getTransactionFlags(), which will also clear the flags,
833ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // with mStateLock held to guarantee that mCurrentState won't change
834ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // until the transaction is committed.
835ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
836e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    transactionFlags = getTransactionFlags(eTransactionMask);
83787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    handleTransactionLocked(transactionFlags);
838ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
839ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mLastTransactionTime = systemTime() - now;
840ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = 0;
841ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    invalidateHwcGeometry();
842ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // here the transaction has been committed
8433d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian}
844edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
84587baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
8463d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{
8473d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    const LayerVector& currentLayers(mCurrentState.layersSortedByZ);
848edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t count = currentLayers.size();
849edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
850edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
851edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Traversal of the children
852edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * (perform the transaction for each of them if needed)
853edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
854edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
855edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const bool layersNeedTransaction = transactionFlags & eTraversalNeeded;
856edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (layersNeedTransaction) {
857edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (size_t i=0 ; i<count ; i++) {
858076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            const sp<LayerBase>& layer = currentLayers[i];
859edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
860edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (!trFlags) continue;
861edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
862edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const uint32_t flags = layer->doTransaction(0);
863edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (flags & Layer::eVisibleRegion)
864edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mVisibleRegionsDirty = true;
865edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
866edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
867edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
868edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
869edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Perform our own transaction if needed
870edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
871edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
872e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    if (transactionFlags & eDisplayTransactionNeeded) {
87392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        // here we take advantage of Vector's copy-on-write semantics to
87492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        // improve performance by skipping the transaction entirely when
87592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        // know that the lists are identical
876e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const KeyedVector<  wp<IBinder>, DisplayDeviceState>& curr(mCurrentState.displays);
877e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const KeyedVector<  wp<IBinder>, DisplayDeviceState>& draw(mDrawingState.displays);
87892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        if (!curr.isIdenticalTo(draw)) {
879edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
88092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            const size_t cc = curr.size();
88192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            const size_t dc = draw.size();
88292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian
88392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // find the displays that were removed
88492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // (ie: in drawing state but not in current state)
88592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // also handle displays that changed
88692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // (ie: displays that are in both lists)
88792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            for (size_t i=0 ; i<dc ; i++) {
888e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                const ssize_t j = curr.indexOfKey(draw.keyAt(i));
889e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                if (j < 0) {
89092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    // in drawing state but not in current state
89192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    if (draw[i].id != DisplayDevice::DISPLAY_ID_MAIN) {
89292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                        mDisplays.removeItem(draw[i].id);
89392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    } else {
89492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                        ALOGW("trying to remove the main display");
89592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    }
89692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                } else {
89792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    // this display is in both lists. see if something changed.
898e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                    const DisplayDeviceState& state(curr[j]);
899e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                    if (state.surface != draw[i].surface) {
900e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        // changing the surface is like destroying and
901e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        // recreating the DisplayDevice
902e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
903e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        sp<SurfaceTextureClient> stc(
904e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                                new SurfaceTextureClient(state.surface));
905e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
906e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        sp<DisplayDevice> disp = new DisplayDevice(this,
907e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                                state.id, stc, 0, mEGLConfig);
908e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
909e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        disp->setLayerStack(state.layerStack);
910e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        disp->setOrientation(state.orientation);
911e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        // TODO: take viewport and frame into account
912e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        mDisplays.replaceValueFor(state.id, disp);
913e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                    }
91492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    if (state.layerStack != draw[i].layerStack) {
9154297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                        const sp<DisplayDevice>& disp(getDisplayDevice(state.id));
91628947d7fbf9f486539322e8e12dd057568e180c2Mathias Agopian                        disp->setLayerStack(state.layerStack);
91792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    }
918e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                    if (state.orientation != draw[i].orientation ||
919e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        state.viewport != draw[i].viewport ||
920e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        state.frame != draw[i].frame) {
9214297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                        const sp<DisplayDevice>& disp(getDisplayDevice(state.id));
9224297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                        disp->setOrientation(state.orientation);
923e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        // TODO: take viewport and frame into account
92492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    }
92592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                }
92692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            }
92792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian
92892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // find displays that were added
92992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // (ie: in current state but not in drawing state)
93092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            for (size_t i=0 ; i<cc ; i++) {
931e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                if (draw.indexOfKey(curr.keyAt(i)) < 0) {
93292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    // FIXME: we need to pass the surface here
933e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                    const DisplayDeviceState& state(curr[i]);
934e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                    sp<SurfaceTextureClient> stc(
935e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                            new SurfaceTextureClient(state.surface));
936e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                    sp<DisplayDevice> disp = new DisplayDevice(this, state.id,
937e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                            stc, 0, mEGLConfig);
938e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                    mDisplays.add(state.id, disp);
93992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                }
94092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            }
941edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
942edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
9430aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        if (currentLayers.size() > mDrawingState.layersSortedByZ.size()) {
9440aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            // layers have been added
945edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
946edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
947edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
9480aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        // some layers might have been removed, so
9490aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        // we need to update the regions they're exposing.
9500aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        if (mLayersRemoved) {
95148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian            mLayersRemoved = false;
952edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
9530aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            const LayerVector& previousLayers(mDrawingState.layersSortedByZ);
9543d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian            const size_t count = previousLayers.size();
9553d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian            for (size_t i=0 ; i<count ; i++) {
9560aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                const sp<LayerBase>& layer(previousLayers[i]);
95787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian                if (currentLayers.indexOf(layer) < 0) {
9580aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                    // this layer is not visible anymore
95987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian                    // TODO: we could traverse the tree from front to back and
96087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian                    //       compute the actual visible region
9614fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    // TODO: we could cache the transformed region
9624fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    Layer::State front(layer->drawingState());
9634fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    Region visibleReg = front.transform.transform(
9644fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            Region(Rect(front.active.w, front.active.h)));
96587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian                    invalidateLayerStack(front.layerStack, visibleReg);
9660aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                }
9670aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            }
968edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
969edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
970edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
971edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    commitTransaction();
9724fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
9734fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
9744fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::commitTransaction()
9754fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian{
9764fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    if (!mLayersPendingRemoval.isEmpty()) {
9774fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // Notify removed layers now that they can't be drawn from
9784fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        for (size_t i = 0; i < mLayersPendingRemoval.size(); i++) {
9794fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            mLayersPendingRemoval[i]->onRemoved();
9804fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        }
9814fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        mLayersPendingRemoval.clear();
9824fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
9834fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
9844fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mDrawingState = mCurrentState;
9854fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mTransationPending = false;
9864fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mTransactionCV.broadcast();
987edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
988edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
989edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::computeVisibleRegions(
99087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const LayerVector& currentLayers, uint32_t layerStack,
99187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        Region& outDirtyRegion, Region& outOpaqueRegion)
992edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
993841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
994841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
995edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveOpaqueLayers;
996edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveCoveredLayers;
997edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region dirty;
998edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
99987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    outDirtyRegion.clear();
1000edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1001edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t i = currentLayers.size();
1002edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    while (i--) {
1003076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        const sp<LayerBase>& layer = currentLayers[i];
1004edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1005edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // start with the whole surface at its current location
1006970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian        const Layer::State& s(layer->drawingState());
1007edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
100887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        // only consider the layers on the given later stack
100987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        if (s.layerStack != layerStack)
101087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            continue;
101187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
1012ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
1013ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * opaqueRegion: area of a surface that is fully opaque.
1014ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
1015edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region opaqueRegion;
1016ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1017ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
1018ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visibleRegion: area of a surface that is visible on screen
1019ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * and not fully transparent. This is essentially the layer's
1020ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * footprint minus the opaque regions above it.
1021ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * Areas covered by a translucent surface are considered visible.
1022ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
1023edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region visibleRegion;
1024ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1025ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
1026ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * coveredRegion: area of a surface that is covered by all
1027ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visible regions above it (which includes the translucent areas).
1028ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
1029edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region coveredRegion;
1030ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1031ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1032ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // handle hidden surfaces by setting the visible region to empty
10333165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        if (CC_LIKELY(!(s.flags & layer_state_t::eLayerHidden) && s.alpha)) {
1034a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            const bool translucent = !layer->isOpaque();
10354fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            Rect bounds(layer->computeBounds());
1036edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            visibleRegion.set(bounds);
1037ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            if (!visibleRegion.isEmpty()) {
1038ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // Remove the transparent area from the visible region
1039ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (translucent) {
10404fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    Region transparentRegionScreen;
10414fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    const Transform tr(s.transform);
10424fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    if (tr.transformed()) {
10434fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                        if (tr.preserveRects()) {
10444fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            // transform the transparent region
10454fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            transparentRegionScreen = tr.transform(s.transparentRegion);
10464fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                        } else {
10474fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            // transformation too complex, can't do the
10484fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            // transparent region optimization.
10494fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            transparentRegionScreen.clear();
10504fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                        }
10514fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    } else {
10524fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                        transparentRegionScreen = s.transparentRegion;
10534fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    }
10544fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    visibleRegion.subtractSelf(transparentRegionScreen);
1055ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
1056edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1057ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // compute the opaque region
10584fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                const int32_t layerOrientation = s.transform.getOrientation();
1059ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (s.alpha==255 && !translucent &&
1060ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                        ((layerOrientation & Transform::ROT_INVALID) == false)) {
1061ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    // the opaque region is the layer's footprint
1062ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    opaqueRegion = visibleRegion;
1063ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
1064edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1065edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1066edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1067ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Clip the covered region to the visible region
1068ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        coveredRegion = aboveCoveredLayers.intersect(visibleRegion);
1069ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1070ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveCoveredLayers for next (lower) layer
1071ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        aboveCoveredLayers.orSelf(visibleRegion);
1072ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1073edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // subtract the opaque region covered by the layers above us
1074edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        visibleRegion.subtractSelf(aboveOpaqueLayers);
1075edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1076edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // compute this layer's dirty region
1077edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (layer->contentDirty) {
1078edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // we need to invalidate the whole region
1079edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dirty = visibleRegion;
1080edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // as well, as the old visible region
10814fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            dirty.orSelf(layer->visibleRegion);
1082edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->contentDirty = false;
1083edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
1084a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian            /* compute the exposed region:
1085ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   the exposed region consists of two components:
1086ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   1) what's VISIBLE now and was COVERED before
1087ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   2) what's EXPOSED now less what was EXPOSED before
1088ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
1089ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * note that (1) is conservative, we start with the whole
1090ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * visible region but only keep what used to be covered by
1091ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * something -- which mean it may have been exposed.
1092ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
1093ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * (2) handles areas that were not covered by anything but got
1094ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * exposed because of a resize.
1095a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian             */
1096ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region newExposed = visibleRegion - coveredRegion;
10974fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region oldVisibleRegion = layer->visibleRegion;
10984fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region oldCoveredRegion = layer->coveredRegion;
1099ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldExposed = oldVisibleRegion - oldCoveredRegion;
1100ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed);
1101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirty.subtractSelf(aboveOpaqueLayers);
1103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // accumulate to the screen dirty region
110587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        outDirtyRegion.orSelf(dirty);
1106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1107ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveOpaqueLayers for next (lower) layer
1108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        aboveOpaqueLayers.orSelf(opaqueRegion);
11098b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
1110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // Store the visible region is screen space
1111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setVisibleRegion(visibleRegion);
1112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setCoveredRegion(coveredRegion);
1113edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
111587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    outOpaqueRegion = aboveOpaqueLayers;
1116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
111887baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::invalidateLayerStack(uint32_t layerStack,
111987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const Region& dirty) {
112092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
11214297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
11224297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        if (hw->getLayerStack() == layerStack) {
11234297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->dirtyRegion.orSelf(dirty);
112492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        }
112592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    }
112687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian}
112787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
112887baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handlePageFlip()
1129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
11301c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
11314fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    Region dirtyRegion;
113299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
11331bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian    const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
1134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
11354fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    bool visibleRegions = false;
11364fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    const size_t count = currentLayers.size();
11374fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    sp<LayerBase> const* layers = currentLayers.array();
11384fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    for (size_t i=0 ; i<count ; i++) {
11394fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        const sp<LayerBase>& layer(layers[i]);
114087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const Region dirty(layer->latchBuffer(visibleRegions));
114187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        Layer::State s(layer->drawingState());
114287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        invalidateLayerStack(s.layerStack, dirty);
11434fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
11444da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
11453b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    mVisibleRegionsDirty |= visibleRegions;
1146edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1147edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1148ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopianvoid SurfaceFlinger::invalidateHwcGeometry()
1149ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian{
1150ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian    mHwWorkListDirty = true;
1151ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian}
1152ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian
115399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::handleRefresh()
115499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
115599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    bool needInvalidate = false;
115699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
115799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    const size_t count = currentLayers.size();
115899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
115999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
116099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        if (layer->onPreComposition()) {
116199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            needInvalidate = true;
116299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        }
116399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    }
116499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    if (needInvalidate) {
116599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        signalLayerUpdate();
116699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    }
116799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
116899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
11694297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopianvoid SurfaceFlinger::handleRepaint(const sp<const DisplayDevice>& hw,
117087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const Region& inDirtyRegion)
1171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1172841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
1173841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
117487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    Region dirtyRegion(inDirtyRegion);
117587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
1176b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // compute the invalid region
11774297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->swapRegion.orSelf(dirtyRegion);
1178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
117999ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten    if (CC_UNLIKELY(mDebugRegion)) {
118087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        debugFlashRegions(hw, dirtyRegion);
1181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
11834297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    uint32_t flags = hw->getFlags();
11840f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian    if (flags & DisplayDevice::SWAP_RECTANGLE) {
118529d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // we can redraw only what's dirty, but since SWAP_RECTANGLE only
118629d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // takes a rectangle, we must make sure to update that whole
118729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // rectangle in that case
11884297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        dirtyRegion.set(hw->swapRegion.bounds());
1189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
11900f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian        if (flags & DisplayDevice::PARTIAL_UPDATES) {
119129d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // We need to redraw the rectangle that will be updated
1192df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian            // (pushed to the framebuffer).
119395a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian            // This is needed because PARTIAL_UPDATES only takes one
11940f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian            // rectangle instead of a region (see DisplayDevice::flip())
11954297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            dirtyRegion.set(hw->swapRegion.bounds());
1196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
119729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // we need to redraw everything (the whole screen)
11984297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            dirtyRegion.set(hw->bounds());
11994297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->swapRegion = dirtyRegion;
1200edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1201edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1202edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
120387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    composeSurfaces(hw, dirtyRegion);
1204edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1205d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
1206d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    const size_t count = currentLayers.size();
1207d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
1208d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        currentLayers[i]->onPostComposition();
1209d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    }
1210d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
12119c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    // update the swap region and clear the dirty region
12124297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->swapRegion.orSelf(dirtyRegion);
1213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
12154297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopianvoid SurfaceFlinger::composeSurfaces(const sp<const DisplayDevice>& hw, const Region& dirty)
1216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
12178630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    HWComposer& hwc(getHwComposer());
12181e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian    int32_t id = hw->getDisplayId();
12191e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian    HWComposer::LayerListIterator cur = hwc.begin(id);
12201e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian    const HWComposer::LayerListIterator end = hwc.end(id);
1221a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
12221e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian    const size_t fbLayerCount = hwc.getLayerCount(id, HWC_FRAMEBUFFER);
122352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    if (cur==end || fbLayerCount) {
1224a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
12250f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian        DisplayDevice::makeCurrent(hw, mEGLContext);
1226a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
122752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        // set the frame buffer
122852bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        glMatrixMode(GL_MODELVIEW);
122952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        glLoadIdentity();
1230a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
1231a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        // Never touch the framebuffer if we don't have any framebuffer layers
12321e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian        if (hwc.getLayerCount(id, HWC_OVERLAY)) {
1233b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // when using overlays, we assume a fully transparent framebuffer
1234b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // NOTE: we could reduce how much we need to clear, for instance
1235b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // remove where there are opaque FB layers. however, on some
1236b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // GPUs doing a "clean slate" glClear might be more efficient.
1237b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // We'll revisit later if needed.
1238b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            glClearColor(0, 0, 0, 0);
1239b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            glClear(GL_COLOR_BUFFER_BIT);
1240b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian        } else {
12414297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            const Region region(hw->undefinedRegion.intersect(dirty));
1242b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // screen is already cleared here
124387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            if (!region.isEmpty()) {
1244b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                // can happen with SurfaceView
124587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian                drawWormhole(region);
1246b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            }
1247a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        }
12484b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian
1249a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        /*
1250a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian         * and then, render the layers targeted at the framebuffer
1251a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian         */
12524b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian
12534297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const Vector< sp<LayerBase> >& layers(hw->getVisibleLayersSortedByZ());
1254a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        const size_t count = layers.size();
12554297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const Transform& tr = hw->getTransform();
1256a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall        for (size_t i=0 ; i<count ; ++i) {
1257a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian            const sp<LayerBase>& layer(layers[i]);
12584fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region clip(dirty.intersect(tr.transform(layer->visibleRegion)));
1259a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian            if (!clip.isEmpty()) {
1260a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall                if (cur != end && cur->getCompositionType() == HWC_OVERLAY) {
12613e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian                    if (i && (cur->getHints() & HWC_HINT_CLEAR_FB)
1262a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                            && layer->isOpaque()) {
1263b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                        // never clear the very first layer since we're
1264b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                        // guaranteed the FB is already cleared
12651b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian                        layer->clearWithOpenGL(hw, clip);
1266a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                    }
12676ee93c0d36dff1339eb2428be2d65441398e6e5fJesse Hall                    ++cur;
1268a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                    continue;
1269a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                }
1270a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                // render the layer
12711b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian                layer->draw(hw, clip);
12724b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian            }
1273a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall            if (cur != end) {
1274a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall                ++cur;
1275a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall            }
12764b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian        }
12774b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian    }
1278edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
12804297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopianvoid SurfaceFlinger::debugFlashRegions(const sp<const DisplayDevice>& hw,
128187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const Region& dirtyRegion)
1282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
12834297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const uint32_t flags = hw->getFlags();
12844297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const int32_t height = hw->getHeight();
12854297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    if (hw->swapRegion.isEmpty()) {
128653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian        return;
128753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian    }
12880a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
12890f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian    if (!(flags & DisplayDevice::SWAP_RECTANGLE)) {
12900f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian        const Region repaint((flags & DisplayDevice::PARTIAL_UPDATES) ?
12914297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                dirtyRegion.bounds() : hw->bounds());
12921b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian        composeSurfaces(hw, repaint);
12930a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    }
12940a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
1295c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_EXTERNAL_OES);
1296c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_2D);
1297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_BLEND);
1298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
12990926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    static int toggle = 0;
13000926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    toggle = 1 - toggle;
13010926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    if (toggle) {
13020a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        glColor4f(1, 0, 1, 1);
13030926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    } else {
13040a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        glColor4f(1, 1, 0, 1);
13050926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    }
1306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
130787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    Region::const_iterator it = dirtyRegion.begin();
130887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    Region::const_iterator const end = dirtyRegion.end();
130920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    while (it != end) {
131020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        const Rect& r = *it++;
1311edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLfloat vertices[][2] = {
131253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.left,  height - r.top },
131353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.left,  height - r.bottom },
131453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.right, height - r.bottom },
131553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.right, height - r.top }
1316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        };
1317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glVertexPointer(2, GL_FLOAT, 0, vertices);
1318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
13200a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
13214297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->flip(hw->swapRegion);
1322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1323edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mDebugRegion > 1)
13240a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        usleep(mDebugRegion * 1000);
1325edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1326edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
132787baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::drawWormhole(const Region& region) const
1328edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1329f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    glDisable(GL_TEXTURE_EXTERNAL_OES);
1330b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian    glDisable(GL_TEXTURE_2D);
1331f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    glDisable(GL_BLEND);
1332b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian    glColor4f(0,0,0,0);
1333f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian
1334f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    GLfloat vertices[4][2];
1335f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    glVertexPointer(2, GL_FLOAT, 0, vertices);
1336f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    Region::const_iterator it = region.begin();
1337f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    Region::const_iterator const end = region.end();
1338f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    while (it != end) {
1339f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        const Rect& r = *it++;
1340f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[0][0] = r.left;
1341f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[0][1] = r.top;
1342f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[1][0] = r.right;
1343f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[1][1] = r.top;
1344f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[2][0] = r.right;
1345f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[2][1] = r.bottom;
1346f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[3][0] = r.left;
1347f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[3][1] = r.bottom;
1348f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1349f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    }
1350edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1351edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
135296f0819f81293076e652792794a961543e6750d7Mathias Agopianssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
135396f0819f81293076e652792794a961543e6750d7Mathias Agopian        const sp<LayerBaseClient>& lbc)
13541b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
135596f0819f81293076e652792794a961543e6750d7Mathias Agopian    // attach this layer to the client
13564f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    size_t name = client->attachLayer(lbc);
13574f113740180b6512b43723c4728f262882dc9b45Mathias Agopian
135896f0819f81293076e652792794a961543e6750d7Mathias Agopian    // add this layer to the current state list
1359921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    Mutex::Autolock _l(mStateLock);
1360921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    mCurrentState.layersSortedByZ.add(lbc);
136196f0819f81293076e652792794a961543e6750d7Mathias Agopian
13624f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    return ssize_t(name);
136396f0819f81293076e652792794a961543e6750d7Mathias Agopian}
136496f0819f81293076e652792794a961543e6750d7Mathias Agopian
136596f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer)
136696f0819f81293076e652792794a961543e6750d7Mathias Agopian{
136796f0819f81293076e652792794a961543e6750d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
136896f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = purgatorizeLayer_l(layer);
136996f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR)
137096f0819f81293076e652792794a961543e6750d7Mathias Agopian        setTransactionFlags(eTransactionNeeded);
137196f0819f81293076e652792794a961543e6750d7Mathias Agopian    return err;
1372edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1373edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1374076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase)
1375edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1376edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase);
1377edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (index >= 0) {
1378076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved = true;
1379edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
1380edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
13813d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    return status_t(index);
1382edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1383edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
13849a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase)
13859a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
138676cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    // First add the layer to the purgatory list, which makes sure it won't
138776cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    // go away, then remove it from the main list (through a transaction).
13889a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    ssize_t err = removeLayer_l(layerBase);
138976cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    if (err >= 0) {
139076cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian        mLayerPurgatory.add(layerBase);
139176cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    }
13928c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian
13932f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall    mLayersPendingRemoval.push(layerBase);
13940b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian
13953d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // it's possible that we don't find a layer, because it might
13963d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // have been destroyed already -- this is not technically an error
139796f0819f81293076e652792794a961543e6750d7Mathias Agopian    // from the user because there is a race between Client::destroySurface(),
139896f0819f81293076e652792794a961543e6750d7Mathias Agopian    // ~Client() and ~ISurface().
13999a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err;
14009a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
14019a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
1402dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopianuint32_t SurfaceFlinger::peekTransactionFlags(uint32_t flags)
1403dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian{
1404dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian    return android_atomic_release_load(&mTransactionFlags);
1405dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian}
1406dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian
1407edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags)
1408edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1409edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return android_atomic_and(~flags, &mTransactionFlags) & flags;
1410edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1411edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1412bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags)
1413edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1414edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t old = android_atomic_or(flags, &mTransactionFlags);
1415edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((old & flags)==0) { // wake the server up
141699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        signalTransaction();
1417edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1418edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return old;
1419edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1420edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
14218b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopianvoid SurfaceFlinger::setTransactionState(
14228b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        const Vector<ComposerState>& state,
14238b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        const Vector<DisplayState>& displays,
14248b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        uint32_t flags)
14258b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian{
1426698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
142728378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    uint32_t transactionFlags = 0;
1428e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
1429e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    size_t count = displays.size();
1430e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
1431e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const DisplayState& s(displays[i]);
1432e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        transactionFlags |= setDisplayStateLocked(s);
1433b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis    }
1434b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis
1435e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    count = state.size();
1436698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
1437698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const ComposerState& s(state[i]);
1438698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        sp<Client> client( static_cast<Client *>(s.client.get()) );
143928378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        transactionFlags |= setClientStateLocked(client, s.state);
1440698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    }
1441386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian
144228378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    if (transactionFlags) {
1443386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // this triggers the transaction
144428378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        setTransactionFlags(transactionFlags);
1445698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian
1446386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // if this is a synchronous transaction, wait for it to take effect
1447386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // before returning.
1448386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        if (flags & eSynchronous) {
1449386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            mTransationPending = true;
1450386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        }
1451386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        while (mTransationPending) {
1452386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
1453386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            if (CC_UNLIKELY(err != NO_ERROR)) {
1454386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                // just in case something goes wrong in SF, return to the
1455386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                // called after a few seconds.
145632397c1cd3327905173b36baa6fd1c579bc328ffSteve Block                ALOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!");
1457386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                mTransationPending = false;
1458386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                break;
1459386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            }
1460cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        }
1461edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1462edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1463edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1464e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setDisplayStateLocked(const DisplayState& s)
1465e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{
1466e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    uint32_t flags = 0;
1467e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    DisplayDeviceState& disp(mCurrentState.displays.editValueFor(s.token));
1468e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    if (disp.id >= 0) {
1469e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const uint32_t what = s.what;
1470e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & DisplayState::eSurfaceChanged) {
1471e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.surface->asBinder() != s.surface->asBinder()) {
1472e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.surface = s.surface;
1473e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
1474e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1475e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1476e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & DisplayState::eLayerStackChanged) {
1477e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.layerStack != s.layerStack) {
1478e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.layerStack = s.layerStack;
1479e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
1480e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1481e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1482e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & DisplayState::eTransformChanged) {
1483e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.orientation != s.orientation) {
1484e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.orientation = s.orientation;
1485e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
1486e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1487e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.frame != s.frame) {
1488e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.frame = s.frame;
1489e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
1490e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1491e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.viewport != s.viewport) {
1492e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.viewport = s.viewport;
1493e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
1494e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1495e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1496e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
1497e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return flags;
1498e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
1499e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
1500e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setClientStateLocked(
1501e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const sp<Client>& client,
1502e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const layer_state_t& s)
1503e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{
1504e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    uint32_t flags = 0;
1505e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    sp<LayerBaseClient> layer(client->getLayerUser(s.surface));
1506e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    if (layer != 0) {
1507e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const uint32_t what = s.what;
1508e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::ePositionChanged) {
1509e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setPosition(s.x, s.y))
1510e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1511e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1512e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eLayerChanged) {
1513e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            // NOTE: index needs to be calculated before we update the state
1514e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
1515e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setLayer(s.z)) {
1516e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.removeAt(idx);
1517e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.add(layer);
1518e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // we need traversal (state changed)
1519e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // AND transaction (list changed)
1520e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTransactionNeeded|eTraversalNeeded;
1521e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1522e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1523e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eSizeChanged) {
1524e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setSize(s.w, s.h)) {
1525e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1526e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1527e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1528e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eAlphaChanged) {
1529e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f)))
1530e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1531e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1532e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eMatrixChanged) {
1533e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setMatrix(s.matrix))
1534e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1535e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1536e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eTransparentRegionChanged) {
1537e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setTransparentRegionHint(s.transparentRegion))
1538e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1539e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1540e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eVisibilityChanged) {
1541e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setFlags(s.flags, s.mask))
1542e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1543e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1544e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eCropChanged) {
1545e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setCrop(s.crop))
1546e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1547e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1548e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eLayerStackChanged) {
1549e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            // NOTE: index needs to be calculated before we update the state
1550e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
1551e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setLayerStack(s.layerStack)) {
1552e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.removeAt(idx);
1553e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.add(layer);
1554e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // we need traversal (state changed)
1555e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // AND transaction (list changed)
1556e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTransactionNeeded|eTraversalNeeded;
1557e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1558e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1559e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
1560e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return flags;
1561e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
1562e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
1563921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopiansp<ISurface> SurfaceFlinger::createLayer(
15640ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        ISurfaceComposerClient::surface_data_t* params,
15650ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const String8& name,
15660ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const sp<Client>& client,
1567edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        DisplayID d, uint32_t w, uint32_t h, PixelFormat format,
1568edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t flags)
1569edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1570076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBaseClient> layer;
1571a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    sp<ISurface> surfaceHandle;
15726e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian
15736e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    if (int32_t(w|h) < 0) {
1574921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        ALOGE("createLayer() failed, w or h is negative (w=%d, h=%d)",
15756e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian                int(w), int(h));
15766e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian        return surfaceHandle;
15776e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    }
15788b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
1579921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    //ALOGD("createLayer for (%d x %d), name=%s", w, h, name.string());
15803165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian    switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {
15813165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        case ISurfaceComposerClient::eFXSurfaceNormal:
1582921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian            layer = createNormalLayer(client, d, w, h, flags, format);
1583edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
15843165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        case ISurfaceComposerClient::eFXSurfaceBlur:
15853165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        case ISurfaceComposerClient::eFXSurfaceDim:
1586921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian            layer = createDimLayer(client, d, w, h, flags);
1587edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
15883165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        case ISurfaceComposerClient::eFXSurfaceScreenshot:
1589921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian            layer = createScreenshotLayer(client, d, w, h, flags);
1590118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian            break;
1591edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1592edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1593076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (layer != 0) {
159496f0819f81293076e652792794a961543e6750d7Mathias Agopian        layer->initStates(w, h, flags);
1595285dbde2e0cd0057be070ded3be8f5f453147edcMathias Agopian        layer->setName(name);
159696f0819f81293076e652792794a961543e6750d7Mathias Agopian        ssize_t token = addClientLayer(client, layer);
1597edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        surfaceHandle = layer->getSurface();
15988b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber        if (surfaceHandle != 0) {
159996f0819f81293076e652792794a961543e6750d7Mathias Agopian            params->token = token;
1600a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            params->identity = layer->getIdentity();
16011c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        }
160296f0819f81293076e652792794a961543e6750d7Mathias Agopian        setTransactionFlags(eTransactionNeeded);
1603edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1604edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1605edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return surfaceHandle;
1606edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1607edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1608921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopiansp<Layer> SurfaceFlinger::createNormalLayer(
1609f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        const sp<Client>& client, DisplayID display,
161096f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags,
16111c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        PixelFormat& format)
1612edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1613edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize the surfaces
161492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    switch (format) {
1615edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSPARENT:
1616edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSLUCENT:
1617edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        format = PIXEL_FORMAT_RGBA_8888;
1618edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1619edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_OPAQUE:
1620a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888
1621a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian        format = PIXEL_FORMAT_RGB_565;
1622a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#else
16238f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian        format = PIXEL_FORMAT_RGBX_8888;
1624a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif
1625edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1626edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1627edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1628a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888
1629a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian    if (format == PIXEL_FORMAT_RGBX_8888)
1630a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian        format = PIXEL_FORMAT_RGBA_8888;
1631a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif
1632a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian
163396f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<Layer> layer = new Layer(this, display, client);
1634f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian    status_t err = layer->setBuffers(w, h, format, flags);
163599ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten    if (CC_LIKELY(err != NO_ERROR)) {
1636921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        ALOGE("createNormalLayer() failed (%s)", strerror(-err));
1637076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        layer.clear();
1638edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1639edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1640edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1641edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1642921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopiansp<LayerDim> SurfaceFlinger::createDimLayer(
1643f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        const sp<Client>& client, DisplayID display,
164496f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags)
1645edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
164696f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<LayerDim> layer = new LayerDim(this, display, client);
1647118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    return layer;
1648118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
1649118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
1650921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopiansp<LayerScreenshot> SurfaceFlinger::createScreenshotLayer(
1651118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        const sp<Client>& client, DisplayID display,
1652118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags)
1653118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{
1654118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    sp<LayerScreenshot> layer = new LayerScreenshot(this, display, client);
1655edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1656edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1657edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1658921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianstatus_t SurfaceFlinger::onLayerRemoved(const sp<Client>& client, SurfaceID sid)
16599a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
16609a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    /*
16619a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     * called by the window manager, when a surface should be marked for
16629a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     * destruction.
16638b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber     *
16640aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * The surface is removed from the current and drawing lists, but placed
16650aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * in the purgatory queue, so it's not destroyed right-away (we need
16660aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * to wait for all client's references to go away first).
16679a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     */
16689a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
166948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    status_t err = NAME_NOT_FOUND;
16700aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian    Mutex::Autolock _l(mStateLock);
167196f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<LayerBaseClient> layer = client->getLayerUser(sid);
1672b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam
167348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    if (layer != 0) {
167448d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        err = purgatorizeLayer_l(layer);
167548d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        if (err == NO_ERROR) {
167648d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian            setTransactionFlags(eTransactionNeeded);
167748d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        }
16789a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    }
16799a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return err;
16809a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
16819a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
1682921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianstatus_t SurfaceFlinger::onLayerDestroyed(const wp<LayerBaseClient>& layer)
1683edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1684759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian    // called by ~ISurface() when all references are gone
1685ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    status_t err = NO_ERROR;
1686ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    sp<LayerBaseClient> l(layer.promote());
1687ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    if (l != NULL) {
1688ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        Mutex::Autolock _l(mStateLock);
1689ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        err = removeLayer_l(l);
1690ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        if (err == NAME_NOT_FOUND) {
1691ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // The surface wasn't in the current list, which means it was
1692ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // removed already, which means it is in the purgatory,
1693ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // and need to be removed from there.
1694ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            ssize_t idx = mLayerPurgatory.remove(l);
1695e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block            ALOGE_IF(idx < 0,
1696ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian                    "layer=%p is not in the purgatory list", l.get());
1697f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        }
1698e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE_IF(err<0 && err != NAME_NOT_FOUND,
1699ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian                "error removing layer=%p (%s)", l.get(), strerror(-err));
1700ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    }
1701ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    return err;
1702edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1703edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1704b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// ---------------------------------------------------------------------------
1705b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
1706b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopianvoid SurfaceFlinger::onScreenAcquired() {
17078e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross    ALOGD("Screen about to return, flinger = %p", this);
17084297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    sp<const DisplayDevice> hw(getDefaultDisplayDevice()); // XXX: this should be per DisplayDevice
17098630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    getHwComposer().acquire();
17104297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->acquireScreen();
171122ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian    mEventThread->onScreenAcquired();
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    /*
191082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump SurfaceFlinger global state
191182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
19121b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
191382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "SurfaceFlinger global state:\n");
191482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
19151b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
1916888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian    HWComposer& hwc(getHwComposer());
19174297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    sp<const DisplayDevice> hw(getDefaultDisplayDevice());
191882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const GLExtensions& extensions(GLExtensions::getInstance());
191982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "GLES: %s, %s, %s\n",
192082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            extensions.getVendor(),
192182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            extensions.getRenderer(),
192282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            extensions.getVersion());
192382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
1924d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
192582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "EGL : %s\n",
1926d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian            eglQueryString(mEGLDisplay, EGL_VERSION_HW_ANDROID));
192782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
192873d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian
192982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "EXTS: %s\n", extensions.getExtension());
193082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
19319795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
19324297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->undefinedRegion.dump(result, "undefinedRegion");
193382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE,
193482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  orientation=%d, canDraw=%d\n",
19354297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->getOrientation(), hw->canDraw());
193682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
193782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE,
193882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  last eglSwapBuffers() time: %f us\n"
193982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  last transaction time     : %f us\n"
1940c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian            "  transaction-flags         : %08x\n"
194182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  refresh-rate              : %f fps\n"
194282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  x-dpi                     : %f\n"
1943b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian            "  y-dpi                     : %f\n"
1944b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian            "  density                   : %f\n",
194582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mLastSwapBufferTime/1000.0,
194682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mLastTransactionTime/1000.0,
1947c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian            mTransactionFlags,
1948888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian            1e9 / hwc.getRefreshPeriod(),
19494297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->getDpiX(),
19504297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->getDpiY(),
19514297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->getDensity());
195282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
195382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
195482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "  eglSwapBuffers time: %f us\n",
195582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            inSwapBuffersDuration/1000.0);
195682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
195782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
195882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "  transaction time: %f us\n",
195982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            inTransactionDuration/1000.0);
196082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
196182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
196282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
196382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * VSYNC state
196482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
196582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    mEventThread->dump(result, buffer, SIZE);
196682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
196782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
196882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump HWComposer state
196982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
197082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "h/w composer state:\n");
197182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
197282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "  h/w composer %s and %s\n",
197382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            hwc.initCheck()==NO_ERROR ? "present" : "not present",
197482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                    (mDebugDisableHWC || mDebugRegion) ? "disabled" : "enabled");
197582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
19764297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hwc.dump(result, buffer, SIZE, hw->getVisibleLayersSortedByZ());
197782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
197882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
197982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump gralloc state
198082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
198182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
198282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    alloc.dump(result);
19834297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->dump(result);
1984edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1985edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1986edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::onTransact(
1987edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
1988edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1989edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (code) {
1990edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case CREATE_CONNECTION:
1991698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        case SET_TRANSACTION_STATE:
1992edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case BOOT_FINISHED:
19938e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross        case BLANK:
19948e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross        case UNBLANK:
1995edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        {
1996edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // codes that require permission check
1997edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            IPCThreadState* ipc = IPCThreadState::self();
1998edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int pid = ipc->getCallingPid();
1999a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian            const int uid = ipc->getCallingUid();
200099b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
200199b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) {
2002e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block                ALOGE("Permission Denial: "
2003375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                        "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
2004375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                return PERMISSION_DENIED;
2005edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
20061b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
20071b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
20081b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        case CAPTURE_SCREEN:
20091b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
20101b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            // codes that require permission check
20111b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
20121b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int pid = ipc->getCallingPid();
20131b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int uid = ipc->getCallingUid();
201499b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
201599b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) {
2016e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block                ALOGE("Permission Denial: "
20171b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                        "can't read framebuffer pid=%d, uid=%d", pid, uid);
20181b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                return PERMISSION_DENIED;
20191b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            }
20201b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
2021edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
2022edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
20231b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
2024edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
2025edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
2026b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        CHECK_INTERFACE(ISurfaceComposer, data, reply);
202799ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten        if (CC_UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) {
2028375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
2029375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int pid = ipc->getCallingPid();
2030375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int uid = ipc->getCallingUid();
2031e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block            ALOGE("Permission Denial: "
2032375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                    "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
2033edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return PERMISSION_DENIED;
2034edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
2035edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int n;
2036edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        switch (code) {
203701b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian            case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE
203835b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian            case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE
2039edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
2040edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1002:  // SHOW_UPDATES
2041edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                n = data.readInt32();
2042edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDebugRegion = n ? n : (mDebugRegion ? 0 : 1);
204353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
204453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
2045edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
2046edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1004:{ // repaint everything
204753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
2048cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
2049cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            }
2050cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            case 1005:{ // force transaction
2051e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                setTransactionFlags(
2052e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        eTransactionNeeded|
2053e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        eDisplayTransactionNeeded|
2054e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        eTraversalNeeded);
2055cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
2056edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
20574d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            case 1006:{ // send empty update
20584d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian                signalRefresh();
20594d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian                return NO_ERROR;
20604d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            }
206153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian            case 1008:  // toggle use of hw composer
206253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                n = data.readInt32();
206353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                mDebugDisableHWC = n ? 1 : 0;
206453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
206553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
206653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                return NO_ERROR;
2067a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian            case 1009:  // toggle use of transform hint
2068a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                n = data.readInt32();
2069a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                mDebugDisableTransformHint = n ? 1 : 0;
2070a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                invalidateHwcGeometry();
2071a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                repaintEverything();
2072a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                return NO_ERROR;
2073edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1010:  // interrogate.
207401b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian                reply->writeInt32(0);
2075edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(0);
2076edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(mDebugRegion);
2077b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                reply->writeInt32(0);
207812839bee29bdcc65731b4d42029cc59e2320c5c4Dianne Hackborn                reply->writeInt32(mDebugDisableHWC);
2079edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
2080edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1013: {
2081edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                Mutex::Autolock _l(mStateLock);
20824297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                sp<const DisplayDevice> hw(getDefaultDisplayDevice());
20834297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                reply->writeInt32(hw->getPageFlipCount());
2084edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
2085edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return NO_ERROR;
2086edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
2087edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2088edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return err;
2089edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2090edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
209153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopianvoid SurfaceFlinger::repaintEverything() {
209287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    android_atomic_or(1, &mRepaintEverything);
209399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    signalTransaction();
209453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian}
209553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian
209659119e658a12279e8fff508f8773843de2d90917Mathias Agopian// ---------------------------------------------------------------------------
209759119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2098118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopianstatus_t SurfaceFlinger::renderScreenToTexture(DisplayID dpy,
2099118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        GLuint* textureName, GLfloat* uOut, GLfloat* vOut)
2100118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{
2101118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    Mutex::Autolock _l(mStateLock);
2102118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    return renderScreenToTextureLocked(dpy, textureName, uOut, vOut);
2103118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
2104118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
21059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::renderScreenToTextureLocked(DisplayID dpy,
21069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        GLuint* textureName, GLfloat* uOut, GLfloat* vOut)
210759119e658a12279e8fff508f8773843de2d90917Mathias Agopian{
210822ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian    ATRACE_CALL();
210922ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian
211059119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
211159119e658a12279e8fff508f8773843de2d90917Mathias Agopian        return INVALID_OPERATION;
211259119e658a12279e8fff508f8773843de2d90917Mathias Agopian
211359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // get screen geometry
21144297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    sp<const DisplayDevice> hw(getDisplayDevice(dpy));
21154297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const uint32_t hw_w = hw->getWidth();
21164297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const uint32_t hw_h = hw->getHeight();
211759119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLfloat u = 1;
211859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLfloat v = 1;
211959119e658a12279e8fff508f8773843de2d90917Mathias Agopian
212059119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // make sure to clear all GL error flags
212159119e658a12279e8fff508f8773843de2d90917Mathias Agopian    while ( glGetError() != GL_NO_ERROR ) ;
212259119e658a12279e8fff508f8773843de2d90917Mathias Agopian
212359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // create a FBO
212459119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLuint name, tname;
212559119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glGenTextures(1, &tname);
212659119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
2127a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2128a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
21299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
21309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            hw_w, hw_h, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
213159119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (glGetError() != GL_NO_ERROR) {
2132015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian        while ( glGetError() != GL_NO_ERROR ) ;
213359119e658a12279e8fff508f8773843de2d90917Mathias Agopian        GLint tw = (2 << (31 - clz(hw_w)));
213459119e658a12279e8fff508f8773843de2d90917Mathias Agopian        GLint th = (2 << (31 - clz(hw_h)));
21359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
21369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian                tw, th, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
213759119e658a12279e8fff508f8773843de2d90917Mathias Agopian        u = GLfloat(hw_w) / tw;
213859119e658a12279e8fff508f8773843de2d90917Mathias Agopian        v = GLfloat(hw_h) / th;
213959119e658a12279e8fff508f8773843de2d90917Mathias Agopian    }
214059119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glGenFramebuffersOES(1, &name);
214159119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
21429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES,
21439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0);
214459119e658a12279e8fff508f8773843de2d90917Mathias Agopian
21459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // redraw the screen entirely...
2146c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_EXTERNAL_OES);
2147c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_2D);
21489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glClearColor(0,0,0,1);
21499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glClear(GL_COLOR_BUFFER_BIT);
2150a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glMatrixMode(GL_MODELVIEW);
2151a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glLoadIdentity();
21524297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const Vector< sp<LayerBase> >& layers(hw->getVisibleLayersSortedByZ());
21539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const size_t count = layers.size();
21549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (size_t i=0 ; i<count ; ++i) {
21559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
2156fcb239d3dac8bc80f28177f1951611c1d43286ffMathias Agopian        layer->draw(hw);
21579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
215859119e658a12279e8fff508f8773843de2d90917Mathias Agopian
21594297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->compositionComplete();
2160118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
21619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // back to main framebuffer
21629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
21639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDeleteFramebuffersOES(1, &name);
216459119e658a12279e8fff508f8773843de2d90917Mathias Agopian
21659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *textureName = tname;
21669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *uOut = u;
21679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *vOut = v;
21689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
21699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
217059119e658a12279e8fff508f8773843de2d90917Mathias Agopian
21719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// ---------------------------------------------------------------------------
21729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
217374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopianstatus_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy,
217474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        sp<IMemoryHeap>* heap,
217574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t* w, uint32_t* h, PixelFormat* f,
2176bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t sw, uint32_t sh,
2177bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ, uint32_t maxLayerZ)
217874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{
2179fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian    ATRACE_CALL();
2180fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian
218174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    status_t result = PERMISSION_DENIED;
218274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
218374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // only one display supported for now
21843b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    if (CC_UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) {
2185ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian        ALOGE("invalid display %d", dpy);
218674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return BAD_VALUE;
21873b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
218874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
21893b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject()) {
219074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return INVALID_OPERATION;
21913b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
219274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
219374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // get screen geometry
21944297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    sp<const DisplayDevice> hw(getDisplayDevice(dpy));
21954297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const uint32_t hw_w = hw->getWidth();
21964297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const uint32_t hw_h = hw->getHeight();
219774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
21983b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    // if we have secure windows on this display, never allow the screen capture
21994297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    if (hw->getSecureLayerVisible()) {
2200ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian        ALOGW("FB is protected: PERMISSION_DENIED");
22013b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        return PERMISSION_DENIED;
22023b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
22033b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
22043b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    if ((sw > hw_w) || (sh > hw_h)) {
2205ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian        ALOGE("size mismatch (%d, %d) > (%d, %d)", sw, sh, hw_w, hw_h);
220674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return BAD_VALUE;
22073b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
220874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
220974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    sw = (!sw) ? hw_w : sw;
221074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    sh = (!sh) ? hw_h : sh;
221174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const size_t size = sw * sh * 4;
2212fcb239d3dac8bc80f28177f1951611c1d43286ffMathias Agopian    const bool filtering = sw != hw_w || sh != hw_h;
221374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
2214ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian//    ALOGD("screenshot: sw=%d, sh=%d, minZ=%d, maxZ=%d",
2215ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian//            sw, sh, minLayerZ, maxLayerZ);
2216c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
221774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // make sure to clear all GL error flags
221874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    while ( glGetError() != GL_NO_ERROR ) ;
221974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
222074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // create a FBO
222174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    GLuint name, tname;
222274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glGenRenderbuffersOES(1, &tname);
222374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindRenderbufferOES(GL_RENDERBUFFER_OES, tname);
222474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA8_OES, sw, sh);
2225fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian
222674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glGenFramebuffersOES(1, &name);
222774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
222874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES,
222974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, tname);
223074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
223174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
2232c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
223374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    if (status == GL_FRAMEBUFFER_COMPLETE_OES) {
223474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
223574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // invert everything, b/c glReadPixel() below will invert the FB
223674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glViewport(0, 0, sw, sh);
223774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_PROJECTION);
223874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glPushMatrix();
223974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glLoadIdentity();
2240ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian        glOrthof(0, hw_w, hw_h, 0, 0, 1);
224174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_MODELVIEW);
224274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
224374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // redraw the screen entirely...
224474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glClearColor(0,0,0,1);
224574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
2246f653b897a449e10d6cbfb6e0812f7b0bb02d6482Mathias Agopian
22479575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        const LayerVector& layers(mDrawingState.layersSortedByZ);
22489575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        const size_t count = layers.size();
224974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        for (size_t i=0 ; i<count ; ++i) {
225074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            const sp<LayerBase>& layer(layers[i]);
2251b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian            const uint32_t flags = layer->drawingState().flags;
22523165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian            if (!(flags & layer_state_t::eLayerHidden)) {
2253b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                const uint32_t z = layer->drawingState().z;
2254b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                if (z >= minLayerZ && z <= maxLayerZ) {
2255fcb239d3dac8bc80f28177f1951611c1d43286ffMathias Agopian                    if (filtering) layer->setFiltering(true);
2256fcb239d3dac8bc80f28177f1951611c1d43286ffMathias Agopian                    layer->draw(hw);
2257fcb239d3dac8bc80f28177f1951611c1d43286ffMathias Agopian                    if (filtering) layer->setFiltering(false);
2258b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                }
2259bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian            }
226074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        }
226174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
226274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // check for errors and return screen capture
226374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        if (glGetError() != GL_NO_ERROR) {
226474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // error while rendering
226574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            result = INVALID_OPERATION;
226674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        } else {
226774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // allocate shared memory large enough to hold the
226874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // screen capture
226974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            sp<MemoryHeapBase> base(
227074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    new MemoryHeapBase(size, 0, "screen-capture") );
227174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            void* const ptr = base->getBase();
227274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            if (ptr) {
227374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                // capture the screen with glReadPixels()
2274fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian                ScopedTrace _t(ATRACE_TAG, "glReadPixels");
227574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                glReadPixels(0, 0, sw, sh, GL_RGBA, GL_UNSIGNED_BYTE, ptr);
227674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                if (glGetError() == GL_NO_ERROR) {
227774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *heap = base;
227874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *w = sw;
227974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *h = sh;
228074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *f = PIXEL_FORMAT_RGBA_8888;
228174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    result = NO_ERROR;
228274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                }
228374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            } else {
228474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                result = NO_MEMORY;
228574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            }
228674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        }
228774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glViewport(0, 0, hw_w, hw_h);
228874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_PROJECTION);
228974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glPopMatrix();
229074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_MODELVIEW);
229174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    } else {
229274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        result = BAD_VALUE;
229374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    }
229474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
229574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // release FBO resources
229674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
229774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glDeleteRenderbuffersOES(1, &tname);
229874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glDeleteFramebuffersOES(1, &name);
2299e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian
23004297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->compositionComplete();
2301e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian
2302ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian//    ALOGD("screenshot: result = %s", result<0 ? strerror(result) : "OK");
2303c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
230474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    return result;
230574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian}
230674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
230774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
23081b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopianstatus_t SurfaceFlinger::captureScreen(DisplayID dpy,
23091b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        sp<IMemoryHeap>* heap,
231074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t* width, uint32_t* height, PixelFormat* format,
2311bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t sw, uint32_t sh,
2312bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ, uint32_t maxLayerZ)
23131b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian{
23141b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    // only one display supported for now
231599ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten    if (CC_UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
23161b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        return BAD_VALUE;
23171b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
23181b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
23191b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        return INVALID_OPERATION;
23201b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
23211b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    class MessageCaptureScreen : public MessageBase {
23221b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        SurfaceFlinger* flinger;
23231b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        DisplayID dpy;
23241b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        sp<IMemoryHeap>* heap;
23251b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        uint32_t* w;
23261b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        uint32_t* h;
23271b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        PixelFormat* f;
232874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t sw;
232974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t sh;
2330bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ;
2331bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t maxLayerZ;
23321b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        status_t result;
23331b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    public:
23341b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        MessageCaptureScreen(SurfaceFlinger* flinger, DisplayID dpy,
233574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                sp<IMemoryHeap>* heap, uint32_t* w, uint32_t* h, PixelFormat* f,
2336bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                uint32_t sw, uint32_t sh,
2337bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                uint32_t minLayerZ, uint32_t maxLayerZ)
23381b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            : flinger(flinger), dpy(dpy),
2339bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              heap(heap), w(w), h(h), f(f), sw(sw), sh(sh),
2340bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              minLayerZ(minLayerZ), maxLayerZ(maxLayerZ),
2341bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              result(PERMISSION_DENIED)
23421b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
23431b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
23441b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        status_t getResult() const {
23451b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            return result;
23461b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
23471b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        virtual bool handler() {
23481b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
234974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            result = flinger->captureScreenImplLocked(dpy,
2350bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                    heap, w, h, f, sw, sh, minLayerZ, maxLayerZ);
23511b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            return true;
23521b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
23531b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    };
23541b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
23551b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    sp<MessageBase> msg = new MessageCaptureScreen(this,
2356bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian            dpy, heap, width, height, format, sw, sh, minLayerZ, maxLayerZ);
23571b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    status_t res = postMessageSync(msg);
23581b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    if (res == NO_ERROR) {
23591b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        res = static_cast<MessageCaptureScreen*>( msg.get() )->getResult();
23601b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    }
23611b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    return res;
23621b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian}
23631b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
23641b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// ---------------------------------------------------------------------------
23651b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
2366921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::LayerVector::LayerVector() {
2367921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
2368921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
2369921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::LayerVector::LayerVector(const LayerVector& rhs)
2370921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    : SortedVector<sp<LayerBase> >(rhs) {
2371921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
2372921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
2373921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianint SurfaceFlinger::LayerVector::do_compare(const void* lhs,
2374921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    const void* rhs) const
2375edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2376be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    // sort layers per layer-stack, then by z-order and finally by sequence
2377921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    const sp<LayerBase>& l(*reinterpret_cast<const sp<LayerBase>*>(lhs));
2378921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    const sp<LayerBase>& r(*reinterpret_cast<const sp<LayerBase>*>(rhs));
2379be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian
2380be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    uint32_t ls = l->currentState().layerStack;
2381be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    uint32_t rs = r->currentState().layerStack;
2382be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    if (ls != rs)
2383be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian        return ls - rs;
2384be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian
2385921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    uint32_t lz = l->currentState().z;
2386921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    uint32_t rz = r->currentState().z;
2387be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    if (lz != rz)
2388be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian        return lz - rz;
2389be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian
2390be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    return l->sequence - r->sequence;
2391921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
2392921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
2393921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian// ---------------------------------------------------------------------------
2394921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
2395e57f292595bec48f65c8088b00ff6beea01217e9Mathias AgopianSurfaceFlinger::DisplayDeviceState::DisplayDeviceState() : id(-1) {
2396e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
2397e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
2398e57f292595bec48f65c8088b00ff6beea01217e9Mathias AgopianSurfaceFlinger::DisplayDeviceState::DisplayDeviceState(int32_t id)
2399e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    : id(id), layerStack(0), orientation(0) {
2400b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
24017303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
2402b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// ---------------------------------------------------------------------------
240396f0819f81293076e652792794a961543e6750d7Mathias Agopian
24049a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::GraphicBufferAlloc() {}
24059a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
24069a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::~GraphicBufferAlloc() {}
24079a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
24089a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h,
2409d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        PixelFormat format, uint32_t usage, status_t* error) {
24109a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(w, h, format, usage));
24119a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    status_t err = graphicBuffer->initCheck();
2412d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian    *error = err;
2413a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (err != 0 || graphicBuffer->handle == 0) {
2414d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        if (err == NO_MEMORY) {
2415d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian            GraphicBuffer::dumpAllocationsToSystemLog();
2416d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        }
2417e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE("GraphicBufferAlloc::createGraphicBuffer(w=%d, h=%d) "
2418a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian             "failed (%s), handle=%p",
2419a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                w, h, strerror(-err), graphicBuffer->handle);
24209a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis        return 0;
24219a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    }
24229a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    return graphicBuffer;
24239a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis}
24249a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
24259a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis// ---------------------------------------------------------------------------
24269a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
2427edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
2428