SurfaceFlinger.cpp revision 93997a8a75942b4d06cf50925de5bede489cc134
1edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/*
2edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
3edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
4edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * you may not use this file except in compliance with the License.
6edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * You may obtain a copy of the License at
7edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
8edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
10edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * See the License for the specific language governing permissions and
14edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * limitations under the License.
15edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */
16edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
171c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#define ATRACE_TAG ATRACE_TAG_GRAPHICS
181c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
19edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdint.h>
20921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <sys/types.h>
21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <errno.h>
22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <math.h>
23921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
24921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <EGL/egl.h>
25921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <GLES/gl.h>
26edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
27edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/log.h>
28edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/properties.h>
29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
30c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IPCThreadState.h>
31c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IServiceManager.h>
327303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian#include <binder/MemoryHeapBase.h>
3399b49840d309727678b77403d6cc9f920111623fMathias Agopian#include <binder/PermissionCache.h>
347303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
35c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian#include <ui/DisplayInfo.h>
36c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian
37921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <gui/BitTube.h>
381a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <gui/BufferQueue.h>
391a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <gui/IDisplayEventConnection.h>
40921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <gui/SurfaceTextureClient.h>
41921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
42921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <ui/GraphicBufferAllocator.h>
43921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <ui/PixelFormat.h>
44d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String8.h>
46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String16.h>
47edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/StopWatch.h>
481c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#include <utils/Trace.h>
49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
50921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <private/android_filesystem_config.h>
51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h"
5390ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include "DdmConnection.h"
540f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian#include "DisplayDevice.h"
55db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian#include "Client.h"
56d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian#include "EventThread.h"
571f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian#include "GLExtensions.h"
58edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h"
59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerDim.h"
60118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian#include "LayerScreenshot.h"
61edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h"
62edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
63a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#include "DisplayHardware/FramebufferSurface.h"
64a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian#include "DisplayHardware/HWComposer.h"
65edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
66a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
67bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian#define EGL_VERSION_HW_ANDROID  0x3143
68bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DISPLAY_COUNT       1
70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
73edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
7499b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sHardwareTest("android.permission.HARDWARE_TEST");
7599b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER");
7699b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER");
7799b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sDump("android.permission.DUMP");
7899b49840d309727678b77403d6cc9f920111623fMathias Agopian
7999b49840d309727678b77403d6cc9f920111623fMathias Agopian// ---------------------------------------------------------------------------
8099b49840d309727678b77403d6cc9f920111623fMathias Agopian
81edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::SurfaceFlinger()
82edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    :   BnSurfaceComposer(), Thread(false),
83edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mTransactionFlags(0),
8428378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        mTransationPending(false),
85076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved(false),
8652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        mRepaintEverything(0),
87edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mBootTime(systemTime()),
88edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mVisibleRegionsDirty(false),
89a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        mHwWorkListDirty(false),
90edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDebugRegion(0),
918afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian        mDebugDDMS(0),
9273d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian        mDebugDisableHWC(0),
93a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian        mDebugDisableTransformHint(0),
949795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInSwapBuffers(0),
959795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastSwapBufferTime(0),
969795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInTransaction(0),
979795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastTransactionTime(0),
985f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        mBootFinished(false)
99edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
100a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI("SurfaceFlinger is starting");
101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // debugging stuff...
103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char value[PROPERTY_VALUE_MAX];
1048afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    property_get("debug.sf.showupdates", value, "0");
106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDebugRegion = atoi(value);
1078afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
1088afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    property_get("debug.sf.ddms", value, "0");
1098afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    mDebugDDMS = atoi(value);
1108afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    if (mDebugDDMS) {
1118afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian        DdmConnection::start(getServiceName());
1128afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    }
1138afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
114c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    ALOGI_IF(mDebugRegion, "showupdates enabled");
115c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    ALOGI_IF(mDebugDDMS, "DDMS debugging enabled");
116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
11899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::onFirstRef()
11999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
12099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.init(this);
12199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
12299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY);
12399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
12499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // Wait for the main thread to be done with its initialization
12599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mReadyToRunBarrier.wait();
12699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
12799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
12899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::~SurfaceFlinger()
130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
131a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
132a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
133a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglTerminate(display);
134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
13699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::binderDied(const wp<IBinder>& who)
13799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
13899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // the window manager died on us. prepare its eulogy.
13999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
14013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    // restore initial conditions (default device unblank, etc)
14113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    initializeDisplays();
14299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
14399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // restart the boot-animation
144a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    startBootAnim();
14599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
14699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
1477e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopiansp<ISurfaceComposerClient> SurfaceFlinger::createConnection()
148edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
14996f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<ISurfaceComposerClient> bclient;
15096f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<Client> client(new Client(this));
15196f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = client->initCheck();
15296f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR) {
15396f0819f81293076e652792794a961543e6750d7Mathias Agopian        bclient = client;
154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return bclient;
156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
158e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopiansp<IBinder> SurfaceFlinger::createDisplay()
159e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{
160e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    class DisplayToken : public BBinder {
161e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        sp<SurfaceFlinger> flinger;
162e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        virtual ~DisplayToken() {
163e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             // no more references, this display must be terminated
164e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             Mutex::Autolock _l(flinger->mStateLock);
165e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             flinger->mCurrentState.displays.removeItem(this);
166e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             flinger->setTransactionFlags(eDisplayTransactionNeeded);
167e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian         }
168e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian     public:
169e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        DisplayToken(const sp<SurfaceFlinger>& flinger)
170e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            : flinger(flinger) {
171e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
172e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    };
173e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
174e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    sp<BBinder> token = new DisplayToken(this);
175e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
176e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    Mutex::Autolock _l(mStateLock);
1773ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    DisplayDeviceState info(DisplayDevice::DISPLAY_VIRTUAL);
178e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    mCurrentState.displays.add(token, info);
179e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
180e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return token;
181e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
182e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
183e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopiansp<IBinder> SurfaceFlinger::getBuiltInDisplay(int32_t id) {
1843ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    if (uint32_t(id) >= DisplayDevice::NUM_DISPLAY_TYPES) {
185e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        ALOGE("getDefaultDisplay: id=%d is not a valid default display id", id);
186e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        return NULL;
187e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
188e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return mDefaultDisplays[id];
189e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
190e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
1919a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc()
1929a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis{
1939a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc());
1949a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    return gba;
1959a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis}
196b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::bootFinished()
198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
199edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t now = systemTime();
200edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t duration = now - mBootTime;
201a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
2023330b203039dea366d4981db1408a460134b2d2cMathias Agopian    mBootFinished = true;
2031f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
2041f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // wait patiently for the window manager death
2051f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    const String16 name("window");
2061f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    sp<IBinder> window(defaultServiceManager()->getService(name));
2071f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    if (window != 0) {
208921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        window->linkToDeath(static_cast<IBinder::DeathRecipient*>(this));
2091f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    }
2101f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
2111f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // stop boot animation
212a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // formerly we would just kill the process, but we now ask it to exit so it
213a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // can choose where to stop the animation.
214a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("service.bootanim.exit", "1");
215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
217921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianvoid SurfaceFlinger::deleteTextureAsync(GLuint texture) {
218921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    class MessageDestroyGLTexture : public MessageBase {
219921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        GLuint texture;
220921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    public:
221921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        MessageDestroyGLTexture(GLuint texture)
222921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian            : texture(texture) {
223921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        }
224921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        virtual bool handler() {
225921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian            glDeleteTextures(1, &texture);
226921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian            return true;
227921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        }
228921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    };
229921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    postMessageAsync(new MessageDestroyGLTexture(texture));
230921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
231921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
232a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianstatus_t SurfaceFlinger::selectConfigForPixelFormat(
233a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        EGLDisplay dpy,
234a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        EGLint const* attrs,
235a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        PixelFormat format,
236a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        EGLConfig* outConfig)
237a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian{
238a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLConfig config = NULL;
239a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLint numConfigs = -1, n=0;
240a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglGetConfigs(dpy, NULL, 0, &numConfigs);
241a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLConfig* const configs = new EGLConfig[numConfigs];
242a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglChooseConfig(dpy, attrs, configs, numConfigs, &n);
243a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    for (int i=0 ; i<n ; i++) {
244a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        EGLint nativeVisualId = 0;
245a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        eglGetConfigAttrib(dpy, configs[i], EGL_NATIVE_VISUAL_ID, &nativeVisualId);
246a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        if (nativeVisualId>0 && format == nativeVisualId) {
247a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            *outConfig = configs[i];
248a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            delete [] configs;
249a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            return NO_ERROR;
250a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        }
251a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    }
252a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    delete [] configs;
253a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    return NAME_NOT_FOUND;
254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
256a49126087b4494f4ef50873f3a3f6727265f6621Mathias AgopianEGLConfig SurfaceFlinger::selectEGLConfig(EGLDisplay display, EGLint nativeVisualId) {
257a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // select our EGLConfig. It must support EGL_RECORDABLE_ANDROID if
258a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // it is to be used with WIFI displays
259a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLConfig config;
260a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLint dummy;
261a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    status_t err;
262a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLint attribs[] = {
263a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            EGL_SURFACE_TYPE,           EGL_WINDOW_BIT,
264a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            EGL_RECORDABLE_ANDROID,     EGL_TRUE,
265a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            EGL_NONE
266a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    };
267a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    err = selectConfigForPixelFormat(display, attribs, nativeVisualId, &config);
268a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    if (err) {
269a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        // maybe we failed because of EGL_RECORDABLE_ANDROID
270a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        ALOGW("couldn't find an EGLConfig with EGL_RECORDABLE_ANDROID");
271a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        attribs[2] = EGL_NONE;
272a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        err = selectConfigForPixelFormat(display, attribs, nativeVisualId, &config);
273a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    }
274a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGE_IF(err, "couldn't find an EGLConfig matching the screen format");
275a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    if (eglGetConfigAttrib(display, config, EGL_CONFIG_CAVEAT, &dummy) == EGL_TRUE) {
276a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        ALOGW_IF(dummy == EGL_SLOW_CONFIG, "EGL_SLOW_CONFIG selected!");
277a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    }
278a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    return config;
279a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
281a49126087b4494f4ef50873f3a3f6727265f6621Mathias AgopianEGLContext SurfaceFlinger::createGLContext(EGLDisplay display, EGLConfig config) {
282a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // Also create our EGLContext
283a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLint contextAttributes[] = {
284a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#ifdef EGL_IMG_context_priority
285a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#ifdef HAS_CONTEXT_PRIORITY
286a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#warning "using EGL_IMG_context_priority"
287a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_HIGH_IMG,
288a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#endif
289a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#endif
290a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            EGL_NONE, EGL_NONE
291a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    };
292a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLContext ctxt = eglCreateContext(display, config, NULL, contextAttributes);
293a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGE_IF(ctxt==EGL_NO_CONTEXT, "EGLContext creation failed");
294a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    return ctxt;
295a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
297a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianvoid SurfaceFlinger::initializeGL(EGLDisplay display, EGLSurface surface) {
298a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLBoolean result = eglMakeCurrent(display, surface, surface, mEGLContext);
299a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    if (!result) {
300a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        ALOGE("Couldn't create a working GLES context. check logs. exiting...");
301a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        exit(0);
302edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
304a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    GLExtensions& extensions(GLExtensions::getInstance());
305a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    extensions.initWithGLStrings(
306a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            glGetString(GL_VENDOR),
307a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            glGetString(GL_RENDERER),
308a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            glGetString(GL_VERSION),
309a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            glGetString(GL_EXTENSIONS),
310a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            eglQueryString(display, EGL_VENDOR),
311a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            eglQueryString(display, EGL_VERSION),
312a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            eglQueryString(display, EGL_EXTENSIONS));
3138b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
314a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLint w, h;
315a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglQuerySurface(display, surface, EGL_WIDTH,  &w);
316a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglQuerySurface(display, surface, EGL_HEIGHT, &h);
3178b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
318a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
319a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    glGetIntegerv(GL_MAX_VIEWPORT_DIMS, mMaxViewportDims);
3207303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
3228b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber    glPixelStorei(GL_PACK_ALIGNMENT, 4);
323edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glEnableClientState(GL_VERTEX_ARRAY);
324edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glShadeModel(GL_FLAT);
325edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_DITHER);
326edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_CULL_FACE);
327edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
328a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    struct pack565 {
329a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        inline uint16_t operator() (int r, int g, int b) const {
330a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            return (r<<11)|(g<<5)|b;
331a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        }
332a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    } pack565;
333a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
3349575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    const uint16_t protTexData[] = { pack565(0x03, 0x03, 0x03) };
3359575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glGenTextures(1, &mProtectedTexName);
3369575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glBindTexture(GL_TEXTURE_2D, mProtectedTexName);
3379575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3389575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3399575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
3409575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
3419575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0,
3429575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis            GL_RGB, GL_UNSIGNED_SHORT_5_6_5, protTexData);
343edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
344edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glViewport(0, 0, w, h);
345edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glMatrixMode(GL_PROJECTION);
346edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glLoadIdentity();
347ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    // put the origin in the left-bottom corner
348ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    glOrthof(0, w, 0, h, 0, 1); // l=0, r=w ; b=0, t=h
349edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
350a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // print some debugging info
351a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLint r,g,b,a;
352a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglGetConfigAttrib(display, mEGLConfig, EGL_RED_SIZE,   &r);
353a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglGetConfigAttrib(display, mEGLConfig, EGL_GREEN_SIZE, &g);
354a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglGetConfigAttrib(display, mEGLConfig, EGL_BLUE_SIZE,  &b);
355a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglGetConfigAttrib(display, mEGLConfig, EGL_ALPHA_SIZE, &a);
356a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("EGL informations:");
357a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("vendor    : %s", extensions.getEglVendor());
358a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("version   : %s", extensions.getEglVersion());
359a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("extensions: %s", extensions.getEglExtension());
360a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("Client API: %s", eglQueryString(display, EGL_CLIENT_APIS)?:"Not Supported");
361a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("EGLSurface: %d-%d-%d-%d, config=%p", r, g, b, a, mEGLConfig);
362a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("OpenGL ES informations:");
363a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("vendor    : %s", extensions.getVendor());
364a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("renderer  : %s", extensions.getRenderer());
365a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("version   : %s", extensions.getVersion());
366a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("extensions: %s", extensions.getExtension());
367a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("GL_MAX_TEXTURE_SIZE = %d", mMaxTextureSize);
368a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("GL_MAX_VIEWPORT_DIMS = %d x %d", mMaxViewportDims[0], mMaxViewportDims[1]);
369a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
370a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
371a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianstatus_t SurfaceFlinger::readyToRun()
372a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian{
373a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI(  "SurfaceFlinger's main thread ready to run. "
374a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            "Initializing graphics H/W...");
375a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
376a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // initialize EGL
37734a09ba1efd706323a15633da5044b352988eb5fJesse Hall    mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
37834a09ba1efd706323a15633da5044b352988eb5fJesse Hall    eglInitialize(mEGLDisplay, NULL, NULL);
379a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
380a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // Initialize the main display
381a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // create native window to main display
3821a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    sp<FramebufferSurface> fbs = FramebufferSurface::create();
3831a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    if (fbs == NULL) {
384a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        ALOGE("Display subsystem failed to initialize. check logs. exiting...");
385a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        exit(0);
386a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    }
387a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
388e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    sp<SurfaceTextureClient> stc(new SurfaceTextureClient(
389e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            static_cast<sp<ISurfaceTexture> >(fbs->getBufferQueue())));
3901a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
391a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // initialize the config and context
392a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    int format;
3931a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    ANativeWindow* const anw = stc.get();
3941a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    anw->query(anw, NATIVE_WINDOW_FORMAT, &format);
39534a09ba1efd706323a15633da5044b352988eb5fJesse Hall    mEGLConfig  = selectEGLConfig(mEGLDisplay, format);
39634a09ba1efd706323a15633da5044b352988eb5fJesse Hall    mEGLContext = createGLContext(mEGLDisplay, mEGLConfig);
397a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
398a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // initialize our main display hardware
399e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
4003ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    for (size_t i=0 ; i<DisplayDevice::NUM_DISPLAY_TYPES ; i++) {
401e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        mDefaultDisplays[i] = new BBinder();
4023ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian        mCurrentState.displays.add(mDefaultDisplays[i],
4033ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian                DisplayDeviceState((DisplayDevice::DisplayType)i));
404e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
405e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    sp<DisplayDevice> hw = new DisplayDevice(this,
4063ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian            DisplayDevice::DISPLAY_PRIMARY,
4073ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian            mDefaultDisplays[DisplayDevice::DISPLAY_PRIMARY],
408e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian            anw, fbs, mEGLConfig);
4093ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    mDisplays.add(mDefaultDisplays[DisplayDevice::DISPLAY_PRIMARY], hw);
410a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
411a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    //  initialize OpenGL ES
4124297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    EGLSurface surface = hw->getEGLSurface();
41334a09ba1efd706323a15633da5044b352988eb5fJesse Hall    initializeGL(mEGLDisplay, surface);
414d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
415028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian    // start the EventThread
416028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian    mEventThread = new EventThread(this);
417028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian    mEventQueue.setEventThread(mEventThread);
418028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian
4198630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    // initialize the H/W composer
4208b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    mHwc = new HWComposer(this,
4218b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            *static_cast<HWComposer::EventHandler *>(this),
4228b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            fbs->getFbHal());
42392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian
42492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    // initialize our drawing state
42592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    mDrawingState = mCurrentState;
4268630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
427a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // We're now ready to accept clients...
428d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian    mReadyToRunBarrier.open();
429d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
43013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    // set initial conditions (e.g. unblank default device)
43113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    initializeDisplays();
43213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
433a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    // start boot animation
434a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    startBootAnim();
4358b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
436edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
437edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
438edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
4393ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopianint32_t SurfaceFlinger::allocateHwcDisplayId(DisplayDevice::DisplayType type) {
4403ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    return (uint32_t(type) < DisplayDevice::NUM_DISPLAY_TYPES) ?
4413ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian            type : mHwc->allocateDisplayId();
4423ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian}
4433ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian
444a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopianvoid SurfaceFlinger::startBootAnim() {
445a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // start boot animation
446a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("service.bootanim.exit", "0");
447a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("ctl.start", "bootanim");
448a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian}
449a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian
450a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianuint32_t SurfaceFlinger::getMaxTextureSize() const {
451a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    return mMaxTextureSize;
452a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
453a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
454a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianuint32_t SurfaceFlinger::getMaxViewportDims() const {
455a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    return mMaxViewportDims[0] < mMaxViewportDims[1] ?
456a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            mMaxViewportDims[0] : mMaxViewportDims[1];
457a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
458a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
459edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
460d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
461582270d69db94286a248bd829f1ae6f910d45124Jamie Gennisbool SurfaceFlinger::authenticateSurfaceTexture(
462582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis        const sp<ISurfaceTexture>& surfaceTexture) const {
463134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    Mutex::Autolock _l(mStateLock);
464582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis    sp<IBinder> surfaceTextureBinder(surfaceTexture->asBinder());
465134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
466134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // Check the visible layer list for the ISurface
467134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
468134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    size_t count = currentLayers.size();
469134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    for (size_t i=0 ; i<count ; i++) {
470134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        const sp<LayerBase>& layer(currentLayers[i]);
471134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        sp<LayerBaseClient> lbc(layer->getLayerBaseClient());
472582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis        if (lbc != NULL) {
473582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder();
474582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            if (lbcBinder == surfaceTextureBinder) {
475582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis                return true;
476582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            }
477134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        }
478134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    }
479134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
480134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // Check the layers in the purgatory.  This check is here so that if a
481582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis    // SurfaceTexture gets destroyed before all the clients are done using it,
482582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis    // the error will not be reported as "surface XYZ is not authenticated", but
483134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // will instead fail later on when the client tries to use the surface,
484134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // which should be reported as "surface XYZ returned an -ENODEV".  The
485134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // purgatorized layers are no less authentic than the visible ones, so this
486134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // should not cause any harm.
487134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    size_t purgatorySize =  mLayerPurgatory.size();
488134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    for (size_t i=0 ; i<purgatorySize ; i++) {
489134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
490134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        sp<LayerBaseClient> lbc(layer->getLayerBaseClient());
491582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis        if (lbc != NULL) {
492582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder();
493582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            if (lbcBinder == surfaceTextureBinder) {
494582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis                return true;
495582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            }
496134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        }
497134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    }
498134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
499134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    return false;
500134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis}
501134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
5029d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brownstatus_t SurfaceFlinger::getDisplayInfo(const sp<IBinder>& display, DisplayInfo* info) {
5039d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown    // TODO: this is mostly here only for compatibility
5049d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown    //       the display size is needed but the display metrics should come from elsewhere
5059d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown    if (display != mDefaultDisplays[ISurfaceComposer::eDisplayIdMain]) {
5069d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown        // TODO: additional displays not yet supported
507c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian        return BAD_INDEX;
508c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian    }
5098b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian
5108b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    const HWComposer& hwc(getHwComposer());
5118b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    float xdpi = hwc.getDpiX();
5128b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    float ydpi = hwc.getDpiY();
5138b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian
5148b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    // TODO: Not sure if display density should handled by SF any longer
5158b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    class Density {
5168b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        static int getDensityFromProperty(char const* propName) {
5178b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            char property[PROPERTY_VALUE_MAX];
5188b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            int density = 0;
5198b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            if (property_get(propName, property, NULL) > 0) {
5208b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian                density = atoi(property);
5218b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            }
5228b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            return density;
5238b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        }
5248b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    public:
5258b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        static int getEmuDensity() {
5268b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            return getDensityFromProperty("qemu.sf.lcd_density"); }
5278b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        static int getBuildDensity()  {
5288b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            return getDensityFromProperty("ro.sf.lcd_density"); }
5298b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    };
5308b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    // The density of the device is provided by a build property
5318b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    float density = Density::getBuildDensity() / 160.0f;
5328b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    if (density == 0) {
5338b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        // the build doesn't provide a density -- this is wrong!
5348b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        // use xdpi instead
5358b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        ALOGE("ro.sf.lcd_density must be defined as a build property");
5368b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        density = xdpi / 160.0f;
5378b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    }
5388b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    if (Density::getEmuDensity()) {
5398b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        // if "qemu.sf.lcd_density" is specified, it overrides everything
5408b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        xdpi = ydpi = density = Density::getEmuDensity();
5418b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        density /= 160.0f;
5428b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    }
5438b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian
5444297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    sp<const DisplayDevice> hw(getDefaultDisplayDevice());
5454297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    info->w = hw->getWidth();
5464297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    info->h = hw->getHeight();
5478b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    info->xdpi = xdpi;
5488b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    info->ydpi = ydpi;
5498b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    info->fps = float(1e9 / hwc.getRefreshPeriod());
5508b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    info->density = density;
5514297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    info->orientation = hw->getOrientation();
552888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian    // TODO: this needs to go away (currently needed only by webkit)
5534297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    getPixelFormatInfo(hw->getFormat(), &info->pixelFormatInfo);
554888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian    return NO_ERROR;
555c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian}
556c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian
557d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian// ----------------------------------------------------------------------------
558d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
559d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopiansp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection() {
5608aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian    return mEventThread->createEventConnection();
561bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian}
562bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
5639d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brownvoid SurfaceFlinger::connectDisplay(const sp<ISurfaceTexture>& surface) {
5643094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
5655f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    sp<IBinder> token;
5663094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    { // scope for the lock
5673094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        Mutex::Autolock _l(mStateLock);
5685f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        token = mExtDisplayToken;
5693094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    }
5703094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
5715f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    if (token == 0) {
5725f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        token = createDisplay();
5733094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    }
5743094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
5755f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    { // scope for the lock
5765f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        Mutex::Autolock _l(mStateLock);
5775f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        if (surface == 0) {
5785f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian            // release our current display. we're guarantee to have
5795f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian            // a reference to it (token), while we hold the lock
5805f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian            mExtDisplayToken = 0;
5815f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        } else {
5825f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian            mExtDisplayToken = token;
5835f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        }
5845f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian
5855f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        DisplayDeviceState& info(mCurrentState.displays.editValueFor(token));
5865f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        info.surface = surface;
5875f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        setTransactionFlags(eDisplayTransactionNeeded);
5885f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    }
5893094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian}
5903094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
591edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
59299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
59399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::waitForEvent() {
59499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.waitMessage();
59599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
59699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
59799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalTransaction() {
59899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.invalidate();
59999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
60099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
60199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalLayerUpdate() {
60299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.invalidate();
60399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
60499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
60599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalRefresh() {
60699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.refresh();
60799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
60899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
60999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg,
61099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        nsecs_t reltime, uint32_t flags) {
61199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return mEventQueue.postMessage(msg, reltime);
61299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
61399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
61499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,
61599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        nsecs_t reltime, uint32_t flags) {
61699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    status_t res = mEventQueue.postMessage(msg, reltime);
61799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    if (res == NO_ERROR) {
61899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        msg->wait();
61999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    }
62099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return res;
62199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
622edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
6234fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianbool SurfaceFlinger::threadLoop() {
624edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    waitForEvent();
62599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return true;
62699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
627edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
6283ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopianvoid SurfaceFlinger::onVSyncReceived(int type, nsecs_t timestamp) {
6293ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    if (uint32_t(type) < DisplayDevice::NUM_DISPLAY_TYPES) {
6303ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian        // we should only receive DisplayDevice::DisplayType from the vsync callback
6313ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian        const wp<IBinder>& token(mDefaultDisplays[type]);
6323ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian        mEventThread->onVSyncReceived(token, timestamp);
6333ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    }
6348630320433bd15aca239522e54e711ef6372ab07Mathias Agopian}
6358630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
6368630320433bd15aca239522e54e711ef6372ab07Mathias Agopianvoid SurfaceFlinger::eventControl(int event, int enabled) {
6378630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    getHwComposer().eventControl(event, enabled);
6388630320433bd15aca239522e54e711ef6372ab07Mathias Agopian}
6398630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
6404fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::onMessageReceived(int32_t what) {
6411c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
64299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    switch (what) {
6434fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    case MessageQueue::INVALIDATE:
6444fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        handleMessageTransaction();
6454fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        handleMessageInvalidate();
6464fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        signalRefresh();
6474fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        break;
6484fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    case MessageQueue::REFRESH:
6494fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        handleMessageRefresh();
6504fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        break;
6514fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
6524fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
653edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
6544fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageTransaction() {
655e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    uint32_t transactionFlags = peekTransactionFlags(eTransactionMask);
6564fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    if (transactionFlags) {
65787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        handleTransaction(transactionFlags);
6584fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
6594fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
660edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
6614fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageInvalidate() {
662cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    ATRACE_CALL();
66387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    handlePageFlip();
6644fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
6653a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian
6664fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageRefresh() {
667cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    ATRACE_CALL();
668cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    preComposition();
669cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    rebuildLayerStacks();
670cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    setUpHWComposer();
671cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    doDebugFlashRegions();
672cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    doComposition();
673cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    postComposition();
674cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
675cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
676cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doDebugFlashRegions()
677cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{
678cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    // is debugging enabled
679cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (CC_LIKELY(!mDebugRegion))
680cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        return;
681cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
682cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    const bool repaintEverything = mRepaintEverything;
683cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
684cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
685cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        if (hw->canDraw()) {
686cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            // transform the dirty region into this screen's coordinate space
687cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            const Region dirtyRegion(hw->getDirtyRegion(repaintEverything));
688cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            if (!dirtyRegion.isEmpty()) {
689cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                // redraw the whole screen
690cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                doComposeSurfaces(hw, Region(hw->bounds()));
691cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
692cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                // and draw the dirty region
693cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                glDisable(GL_TEXTURE_EXTERNAL_OES);
694cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                glDisable(GL_TEXTURE_2D);
695cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                glDisable(GL_BLEND);
696cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                glColor4f(1, 0, 1, 1);
697cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                const int32_t height = hw->getHeight();
698cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                Region::const_iterator it = dirtyRegion.begin();
699cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                Region::const_iterator const end = dirtyRegion.end();
700cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                while (it != end) {
701cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                    const Rect& r = *it++;
702cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                    GLfloat vertices[][2] = {
703cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            { r.left,  height - r.top },
704cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            { r.left,  height - r.bottom },
705cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            { r.right, height - r.bottom },
706cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            { r.right, height - r.top }
707cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                    };
708cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                    glVertexPointer(2, GL_FLOAT, 0, vertices);
709cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
710cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                }
711cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                hw->compositionComplete();
712cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                // FIXME
7133ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian                if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) {
714cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                    eglSwapBuffers(mEGLDisplay, hw->getEGLSurface());
715cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                }
716cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            }
717cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        }
718cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
719cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
720cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    postFramebuffer();
721cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
722cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (mDebugRegion > 1) {
723cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        usleep(mDebugRegion * 1000);
724cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
725cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
726cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
727cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::preComposition()
728cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{
729cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    bool needExtraInvalidate = false;
730cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
731cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    const size_t count = currentLayers.size();
732cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    for (size_t i=0 ; i<count ; i++) {
733cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        if (currentLayers[i]->onPreComposition()) {
734cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            needExtraInvalidate = true;
735cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        }
736cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
737cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (needExtraInvalidate) {
738cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        signalLayerUpdate();
739cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
740cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
741a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
742cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::postComposition()
743cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{
744cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
745cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    const size_t count = currentLayers.size();
746cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    for (size_t i=0 ; i<count ; i++) {
747cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        currentLayers[i]->onPostComposition();
748cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
749cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
750cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
751cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::rebuildLayerStacks() {
752cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    // rebuild the visible layer list per screen
75352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    if (CC_UNLIKELY(mVisibleRegionsDirty)) {
754cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        ATRACE_CALL();
75587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        mVisibleRegionsDirty = false;
75687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        invalidateHwcGeometry();
75787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
75892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
7594297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            const sp<DisplayDevice>& hw(mDisplays[dpy]);
7607e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian            const Transform& tr(hw->getTransform());
7617e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian            const Rect bounds(hw->getBounds());
7627e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian
76387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            Region opaqueRegion;
76487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            Region dirtyRegion;
76587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            computeVisibleRegions(currentLayers,
7664297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                    hw->getLayerStack(), dirtyRegion, opaqueRegion);
76787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
76887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            Vector< sp<LayerBase> > layersSortedByZ;
76987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            const size_t count = currentLayers.size();
77087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            for (size_t i=0 ; i<count ; i++) {
7717e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian                const sp<LayerBase>& layer(currentLayers[i]);
7727e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian                const Layer::State& s(layer->drawingState());
7734297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                if (s.layerStack == hw->getLayerStack()) {
7747e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian                    Region visibleRegion(tr.transform(layer->visibleRegion));
7757e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian                    visibleRegion.andSelf(bounds);
7767e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian                    if (!visibleRegion.isEmpty()) {
7777e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian                        layersSortedByZ.add(layer);
77887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian                    }
77987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian                }
7803b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian            }
7814297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->setVisibleLayersSortedByZ(layersSortedByZ);
7827e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian            hw->undefinedRegion.set(bounds);
7837e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian            hw->undefinedRegion.subtractSelf(tr.transform(opaqueRegion));
7847e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian            hw->dirtyRegion.orSelf(dirtyRegion);
7853b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        }
7863b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
787cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
7883b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
789cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::setUpHWComposer() {
79052bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    HWComposer& hwc(getHwComposer());
79152bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    if (hwc.initCheck() == NO_ERROR) {
79252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        // build the h/w work list
79352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        const bool workListsDirty = mHwWorkListDirty;
79452bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        mHwWorkListDirty = false;
79592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
7964297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            sp<const DisplayDevice> hw(mDisplays[dpy]);
797e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian            const int32_t id = hw->getHwcDisplayId();
798e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian            if (id >= 0) {
799e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                const Vector< sp<LayerBase> >& currentLayers(
800cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                    hw->getVisibleLayersSortedByZ());
801e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                const size_t count = currentLayers.size();
802e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                if (hwc.createWorkList(id, count) >= 0) {
803e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                    HWComposer::LayerListIterator cur = hwc.begin(id);
804e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                    const HWComposer::LayerListIterator end = hwc.end(id);
805e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                    for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
806e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                        const sp<LayerBase>& layer(currentLayers[i]);
807e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian
808e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                        if (CC_UNLIKELY(workListsDirty)) {
809e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                            layer->setGeometry(hw, *cur);
810e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                            if (mDebugDisableHWC || mDebugRegion) {
811e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                                cur->setSkip(true);
812e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                            }
8131e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                        }
81452bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian
815e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                        /*
816e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                         * update the per-frame h/w composer data for each layer
817e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                         * and build the transparent region of the FB
818e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                         */
819e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                        layer->setPerFrameData(hw, *cur);
820e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                    }
8211e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                }
82252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            }
82387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        }
82452bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        status_t err = hwc.prepare();
82552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
82652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    }
827cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
82852bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian
829cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doComposition() {
830cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    ATRACE_CALL();
83152bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    const bool repaintEverything = android_atomic_and(0, &mRepaintEverything);
83292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
8334297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
834cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        if (hw->canDraw()) {
835cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            // transform the dirty region into this screen's coordinate space
836cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            const Region dirtyRegion(hw->getDirtyRegion(repaintEverything));
837cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            if (!dirtyRegion.isEmpty()) {
83852bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian                // repaint the framebuffer (if needed)
839cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                doDisplayComposition(hw, dirtyRegion);
84052bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            }
841cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            hw->dirtyRegion.clear();
842cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            hw->flip(hw->swapRegion);
843cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            hw->swapRegion.clear();
84487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        }
84552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        // inform the h/w that we're done compositing
8464297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        hw->compositionComplete();
8474fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
84852bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    postFramebuffer();
849edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
850edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
851edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer()
852edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
853841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
854b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian
855a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    const nsecs_t now = systemTime();
856a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = now;
857c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall
85852bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    HWComposer& hwc(getHwComposer());
859ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall    if (hwc.initCheck() == NO_ERROR) {
8605f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        // FIXME: EGL spec says:
8615f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        //   "surface must be bound to the calling thread's current context,
8625f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        //    for the current rendering API."
8633ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian        DisplayDevice::makeCurrent(getDefaultDisplayDevice(), mEGLContext);
864e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian        hwc.commit();
86552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    }
86652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian
86792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
8684297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        sp<const DisplayDevice> hw(mDisplays[dpy]);
8694297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const Vector< sp<LayerBase> >& currentLayers(hw->getVisibleLayersSortedByZ());
87052bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        const size_t count = currentLayers.size();
871e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian        int32_t id = hw->getHwcDisplayId();
872e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian        if (id >=0 && hwc.initCheck() == NO_ERROR) {
8731e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian            HWComposer::LayerListIterator cur = hwc.begin(id);
8741e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian            const HWComposer::LayerListIterator end = hwc.end(id);
87552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            for (size_t i = 0; cur != end && i < count; ++i, ++cur) {
876d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian                currentLayers[i]->onLayerDisplayed(hw, &*cur);
87752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            }
878cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        } else {
87952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            for (size_t i = 0; i < count; i++) {
880d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian                currentLayers[i]->onLayerDisplayed(hw, NULL);
88152bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            }
882ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall        }
883e8696a40e09b24b634214684d18526187b316a2fJamie Gennis    }
884e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
885a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mLastSwapBufferTime = systemTime() - now;
886a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = 0;
887edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
888edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
88987baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
890edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
891841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
892841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
893ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    Mutex::Autolock _l(mStateLock);
894ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    const nsecs_t now = systemTime();
895ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = now;
896ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
897ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // Here we're guaranteed that some transaction flags are set
898ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // so we can call handleTransactionLocked() unconditionally.
899ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // We call getTransactionFlags(), which will also clear the flags,
900ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // with mStateLock held to guarantee that mCurrentState won't change
901ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // until the transaction is committed.
902ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
903e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    transactionFlags = getTransactionFlags(eTransactionMask);
90487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    handleTransactionLocked(transactionFlags);
905ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
906ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mLastTransactionTime = systemTime() - now;
907ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = 0;
908ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    invalidateHwcGeometry();
909ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // here the transaction has been committed
9103d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian}
911edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
91287baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
9133d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{
9143d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    const LayerVector& currentLayers(mCurrentState.layersSortedByZ);
915edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t count = currentLayers.size();
916edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
917edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
918edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Traversal of the children
919edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * (perform the transaction for each of them if needed)
920edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
921edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
9223559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    if (transactionFlags & eTraversalNeeded) {
923edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (size_t i=0 ; i<count ; i++) {
924076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            const sp<LayerBase>& layer = currentLayers[i];
925edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
926edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (!trFlags) continue;
927edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
928edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const uint32_t flags = layer->doTransaction(0);
929edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (flags & Layer::eVisibleRegion)
930edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mVisibleRegionsDirty = true;
931edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
932edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
933edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
934edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
9353559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian     * Perform display own transactions if needed
936edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
937edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
938e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    if (transactionFlags & eDisplayTransactionNeeded) {
93992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        // here we take advantage of Vector's copy-on-write semantics to
94092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        // improve performance by skipping the transaction entirely when
94192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        // know that the lists are identical
942e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const KeyedVector<  wp<IBinder>, DisplayDeviceState>& curr(mCurrentState.displays);
943e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const KeyedVector<  wp<IBinder>, DisplayDeviceState>& draw(mDrawingState.displays);
94492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        if (!curr.isIdenticalTo(draw)) {
945edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
94692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            const size_t cc = curr.size();
94793997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                  size_t dc = draw.size();
94892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian
94992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // find the displays that were removed
95092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // (ie: in drawing state but not in current state)
95192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // also handle displays that changed
95292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // (ie: displays that are in both lists)
95392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            for (size_t i=0 ; i<dc ; i++) {
954e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                const ssize_t j = curr.indexOfKey(draw.keyAt(i));
955e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                if (j < 0) {
95692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    // in drawing state but not in current state
9573ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian                    if (!draw[i].isMainDisplay()) {
9583ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian                        mDisplays.removeItem(draw.keyAt(i));
95992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    } else {
96092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                        ALOGW("trying to remove the main display");
96192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    }
96292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                } else {
96392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    // this display is in both lists. see if something changed.
964e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                    const DisplayDeviceState& state(curr[j]);
9653ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian                    const wp<IBinder>& display(curr.keyAt(j));
966111b2d89221722d38f5b5b3ba65904ec22421839Mathias Agopian                    if (state.surface->asBinder() != draw[i].surface->asBinder()) {
967e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        // changing the surface is like destroying and
96893997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // recreating the DisplayDevice, so we just remove it
96993997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // from the drawing state, so that it get re-added
97093997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // below.
97193997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        mDisplays.removeItem(display);
97293997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        mDrawingState.displays.removeItemsAt(i);
97393997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        dc--; i--;
97493997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // at this point we must loop to the next item
97593997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        continue;
97692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    }
97793997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian
97893997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                    const sp<DisplayDevice>& disp(getDisplayDevice(display));
97993997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                    if (disp != NULL) {
98093997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        if (state.layerStack != draw[i].layerStack) {
98193997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                            disp->setLayerStack(state.layerStack);
98293997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        }
98393997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        if (state.orientation != draw[i].orientation ||
98493997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                                state.viewport != draw[i].viewport ||
98593997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                                state.frame != draw[i].frame) {
98693997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                            disp->setOrientation(state.orientation);
98793997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                            // TODO: take viewport and frame into account
98893997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        }
98992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    }
99092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                }
99192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            }
99292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian
99392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // find displays that were added
99492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // (ie: in current state but not in drawing state)
99592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            for (size_t i=0 ; i<cc ; i++) {
996e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                if (draw.indexOfKey(curr.keyAt(i)) < 0) {
997e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                    const DisplayDeviceState& state(curr[i]);
99893997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                    if (state.surface != NULL) {
99993997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        sp<SurfaceTextureClient> stc(
100093997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                                new SurfaceTextureClient(state.surface));
100193997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        const wp<IBinder>& display(curr.keyAt(i));
100293997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        sp<DisplayDevice> disp = new DisplayDevice(this,
100393997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                                state.type, display, stc, 0, mEGLConfig);
100493997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        disp->setLayerStack(state.layerStack);
100593997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        disp->setOrientation(state.orientation);
100693997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // TODO: take viewport and frame into account
100793997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        mDisplays.add(display, disp);
100893997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                    }
100992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                }
101092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            }
1011edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
10123559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    }
1013edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
10143559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    /*
10153559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian     * Perform our own transaction if needed
10163559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian     */
1017edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1018cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    const LayerVector& previousLayers(mDrawingState.layersSortedByZ);
1019cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (currentLayers.size() > previousLayers.size()) {
10203559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        // layers have been added
10213559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        mVisibleRegionsDirty = true;
10223559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    }
10233559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian
10243559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    // some layers might have been removed, so
10253559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    // we need to update the regions they're exposing.
10263559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    if (mLayersRemoved) {
10273559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        mLayersRemoved = false;
10283559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        mVisibleRegionsDirty = true;
10293559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        const size_t count = previousLayers.size();
10303559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        for (size_t i=0 ; i<count ; i++) {
10313559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian            const sp<LayerBase>& layer(previousLayers[i]);
10323559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian            if (currentLayers.indexOf(layer) < 0) {
10333559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                // this layer is not visible anymore
10343559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                // TODO: we could traverse the tree from front to back and
10353559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                //       compute the actual visible region
10363559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                // TODO: we could cache the transformed region
10373559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                Layer::State front(layer->drawingState());
10383559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                Region visibleReg = front.transform.transform(
10393559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                        Region(Rect(front.active.w, front.active.h)));
10403559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                invalidateLayerStack(front.layerStack, visibleReg);
10410aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            }
1042edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1043edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1044edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1045edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    commitTransaction();
10464fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
10474fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
10484fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::commitTransaction()
10494fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian{
10504fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    if (!mLayersPendingRemoval.isEmpty()) {
10514fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // Notify removed layers now that they can't be drawn from
10524fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        for (size_t i = 0; i < mLayersPendingRemoval.size(); i++) {
10534fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            mLayersPendingRemoval[i]->onRemoved();
10544fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        }
10554fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        mLayersPendingRemoval.clear();
10564fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
10574fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
10584fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mDrawingState = mCurrentState;
10594fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mTransationPending = false;
10604fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mTransactionCV.broadcast();
1061edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1062edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1063edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::computeVisibleRegions(
106487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const LayerVector& currentLayers, uint32_t layerStack,
106587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        Region& outDirtyRegion, Region& outOpaqueRegion)
1066edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1067841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
1068841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
1069edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveOpaqueLayers;
1070edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveCoveredLayers;
1071edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region dirty;
1072edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
107387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    outDirtyRegion.clear();
1074edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1075edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t i = currentLayers.size();
1076edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    while (i--) {
1077076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        const sp<LayerBase>& layer = currentLayers[i];
1078edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1079edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // start with the whole surface at its current location
1080970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian        const Layer::State& s(layer->drawingState());
1081edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
108287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        // only consider the layers on the given later stack
108387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        if (s.layerStack != layerStack)
108487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            continue;
108587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
1086ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
1087ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * opaqueRegion: area of a surface that is fully opaque.
1088ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
1089edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region opaqueRegion;
1090ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1091ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
1092ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visibleRegion: area of a surface that is visible on screen
1093ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * and not fully transparent. This is essentially the layer's
1094ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * footprint minus the opaque regions above it.
1095ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * Areas covered by a translucent surface are considered visible.
1096ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
1097edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region visibleRegion;
1098ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1099ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
1100ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * coveredRegion: area of a surface that is covered by all
1101ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visible regions above it (which includes the translucent areas).
1102ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
1103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region coveredRegion;
1104ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1105ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1106ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // handle hidden surfaces by setting the visible region to empty
11073165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        if (CC_LIKELY(!(s.flags & layer_state_t::eLayerHidden) && s.alpha)) {
1108a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            const bool translucent = !layer->isOpaque();
11094fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            Rect bounds(layer->computeBounds());
1110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            visibleRegion.set(bounds);
1111ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            if (!visibleRegion.isEmpty()) {
1112ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // Remove the transparent area from the visible region
1113ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (translucent) {
11144fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    Region transparentRegionScreen;
11154fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    const Transform tr(s.transform);
11164fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    if (tr.transformed()) {
11174fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                        if (tr.preserveRects()) {
11184fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            // transform the transparent region
11194fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            transparentRegionScreen = tr.transform(s.transparentRegion);
11204fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                        } else {
11214fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            // transformation too complex, can't do the
11224fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            // transparent region optimization.
11234fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            transparentRegionScreen.clear();
11244fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                        }
11254fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    } else {
11264fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                        transparentRegionScreen = s.transparentRegion;
11274fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    }
11284fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    visibleRegion.subtractSelf(transparentRegionScreen);
1129ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
1130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1131ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // compute the opaque region
11324fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                const int32_t layerOrientation = s.transform.getOrientation();
1133ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (s.alpha==255 && !translucent &&
1134ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                        ((layerOrientation & Transform::ROT_INVALID) == false)) {
1135ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    // the opaque region is the layer's footprint
1136ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    opaqueRegion = visibleRegion;
1137ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
1138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1141ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Clip the covered region to the visible region
1142ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        coveredRegion = aboveCoveredLayers.intersect(visibleRegion);
1143ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1144ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveCoveredLayers for next (lower) layer
1145ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        aboveCoveredLayers.orSelf(visibleRegion);
1146ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1147edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // subtract the opaque region covered by the layers above us
1148edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        visibleRegion.subtractSelf(aboveOpaqueLayers);
1149edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1150edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // compute this layer's dirty region
1151edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (layer->contentDirty) {
1152edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // we need to invalidate the whole region
1153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dirty = visibleRegion;
1154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // as well, as the old visible region
11554fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            dirty.orSelf(layer->visibleRegion);
1156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->contentDirty = false;
1157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
1158a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian            /* compute the exposed region:
1159ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   the exposed region consists of two components:
1160ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   1) what's VISIBLE now and was COVERED before
1161ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   2) what's EXPOSED now less what was EXPOSED before
1162ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
1163ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * note that (1) is conservative, we start with the whole
1164ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * visible region but only keep what used to be covered by
1165ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * something -- which mean it may have been exposed.
1166ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
1167ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * (2) handles areas that were not covered by anything but got
1168ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * exposed because of a resize.
1169a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian             */
1170ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region newExposed = visibleRegion - coveredRegion;
11714fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region oldVisibleRegion = layer->visibleRegion;
11724fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region oldCoveredRegion = layer->coveredRegion;
1173ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldExposed = oldVisibleRegion - oldCoveredRegion;
1174ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed);
1175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirty.subtractSelf(aboveOpaqueLayers);
1177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // accumulate to the screen dirty region
117987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        outDirtyRegion.orSelf(dirty);
1180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1181ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveOpaqueLayers for next (lower) layer
1182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        aboveOpaqueLayers.orSelf(opaqueRegion);
11838b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
1184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // Store the visible region is screen space
1185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setVisibleRegion(visibleRegion);
1186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setCoveredRegion(coveredRegion);
1187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
118987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    outOpaqueRegion = aboveOpaqueLayers;
1190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
119287baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::invalidateLayerStack(uint32_t layerStack,
119387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const Region& dirty) {
119492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
11954297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
11964297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        if (hw->getLayerStack() == layerStack) {
11974297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->dirtyRegion.orSelf(dirty);
119892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        }
119992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    }
120087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian}
120187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
120287baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handlePageFlip()
1203edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
12044fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    Region dirtyRegion;
120599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
12064fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    bool visibleRegions = false;
1207cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
12084fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    const size_t count = currentLayers.size();
12094fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    for (size_t i=0 ; i<count ; i++) {
1210cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
121187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const Region dirty(layer->latchBuffer(visibleRegions));
121287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        Layer::State s(layer->drawingState());
121387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        invalidateLayerStack(s.layerStack, dirty);
12144fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
12154da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
12163b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    mVisibleRegionsDirty |= visibleRegions;
1217edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1219ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopianvoid SurfaceFlinger::invalidateHwcGeometry()
1220ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian{
1221ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian    mHwWorkListDirty = true;
1222ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian}
1223ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian
122499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
1225cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doDisplayComposition(const sp<const DisplayDevice>& hw,
122687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const Region& inDirtyRegion)
1227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
122887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    Region dirtyRegion(inDirtyRegion);
122987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
1230b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // compute the invalid region
12314297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->swapRegion.orSelf(dirtyRegion);
1232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
12334297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    uint32_t flags = hw->getFlags();
12340f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian    if (flags & DisplayDevice::SWAP_RECTANGLE) {
123529d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // we can redraw only what's dirty, but since SWAP_RECTANGLE only
123629d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // takes a rectangle, we must make sure to update that whole
123729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // rectangle in that case
12384297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        dirtyRegion.set(hw->swapRegion.bounds());
1239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
12400f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian        if (flags & DisplayDevice::PARTIAL_UPDATES) {
124129d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // We need to redraw the rectangle that will be updated
1242df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian            // (pushed to the framebuffer).
124395a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian            // This is needed because PARTIAL_UPDATES only takes one
12440f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian            // rectangle instead of a region (see DisplayDevice::flip())
12454297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            dirtyRegion.set(hw->swapRegion.bounds());
1246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
124729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // we need to redraw everything (the whole screen)
12484297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            dirtyRegion.set(hw->bounds());
12494297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->swapRegion = dirtyRegion;
1250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1253cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    doComposeSurfaces(hw, dirtyRegion);
1254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1255cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    // FIXME: we need to call eglSwapBuffers() on displays that have
1256cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    // GL composition and only on those.
1257cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    // however, currently hwc.commit() already does that for the main
1258cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    // display and never for the other ones
12593ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) {
1260cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        // FIXME: EGL spec says:
1261cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        //   "surface must be bound to the calling thread's current context,
1262cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        //    for the current rendering API."
1263cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        eglSwapBuffers(mEGLDisplay, hw->getEGLSurface());
1264d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    }
1265d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
12669c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    // update the swap region and clear the dirty region
12674297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->swapRegion.orSelf(dirtyRegion);
1268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1269edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1270cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& hw, const Region& dirty)
1271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
127285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    const int32_t id = hw->getHwcDisplayId();
12738630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    HWComposer& hwc(getHwComposer());
12741e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian    HWComposer::LayerListIterator cur = hwc.begin(id);
12751e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian    const HWComposer::LayerListIterator end = hwc.end(id);
1276a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
127785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    const bool hasGlesComposition = hwc.hasGlesComposition(id) || (cur==end);
127885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    if (hasGlesComposition) {
12790f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian        DisplayDevice::makeCurrent(hw, mEGLContext);
1280a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
128152bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        // set the frame buffer
128252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        glMatrixMode(GL_MODELVIEW);
128352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        glLoadIdentity();
1284a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
1285a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        // Never touch the framebuffer if we don't have any framebuffer layers
128685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        const bool hasHwcComposition = hwc.hasHwcComposition(id);
1287e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian        if (hasHwcComposition) {
1288b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // when using overlays, we assume a fully transparent framebuffer
1289b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // NOTE: we could reduce how much we need to clear, for instance
1290b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // remove where there are opaque FB layers. however, on some
1291b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // GPUs doing a "clean slate" glClear might be more efficient.
1292b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // We'll revisit later if needed.
1293b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            glClearColor(0, 0, 0, 0);
1294b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            glClear(GL_COLOR_BUFFER_BIT);
1295b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian        } else {
12964297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            const Region region(hw->undefinedRegion.intersect(dirty));
1297b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // screen is already cleared here
129887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            if (!region.isEmpty()) {
1299b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                // can happen with SurfaceView
130055801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian                drawWormhole(hw, region);
1301b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            }
1302a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        }
130385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    }
13044b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian
130585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    /*
130685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian     * and then, render the layers targeted at the framebuffer
130785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian     */
13084b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian
130985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    const Vector< sp<LayerBase> >& layers(hw->getVisibleLayersSortedByZ());
131085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    const size_t count = layers.size();
131185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    const Transform& tr = hw->getTransform();
131285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    if (cur != end) {
131385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        // we're using h/w composer
131485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        for (size_t i=0 ; i<count && cur!=end ; ++i, ++cur) {
1315a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian            const sp<LayerBase>& layer(layers[i]);
13164fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region clip(dirty.intersect(tr.transform(layer->visibleRegion)));
131785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            if (!clip.isEmpty()) {
131885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                switch (cur->getCompositionType()) {
131985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                    case HWC_OVERLAY: {
132085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                        if ((cur->getHints() & HWC_HINT_CLEAR_FB)
132185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                                && i
132285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                                && layer->isOpaque()
132385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                                && hasGlesComposition) {
1324cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            // never clear the very first layer since we're
1325cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            // guaranteed the FB is already cleared
1326cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            layer->clearWithOpenGL(hw, clip);
1327cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                        }
132885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                        break;
132985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                    }
133085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                    case HWC_FRAMEBUFFER: {
1331cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                        layer->draw(hw, clip);
133285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                        break;
1333a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                    }
1334cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                }
1335a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall            }
133685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            layer->setAcquireFence(hw, *cur);
133785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        }
133885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    } else {
133985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        // we're not using h/w composer
134085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        for (size_t i=0 ; i<count ; ++i) {
134185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            const sp<LayerBase>& layer(layers[i]);
134285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            const Region clip(dirty.intersect(
134385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                    tr.transform(layer->visibleRegion)));
134485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            if (!clip.isEmpty()) {
134585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                layer->draw(hw, clip);
134685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            }
13474b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian        }
13484b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian    }
1349edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1350edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
135155801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopianvoid SurfaceFlinger::drawWormhole(const sp<const DisplayDevice>& hw,
135255801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian        const Region& region) const
1353edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1354f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    glDisable(GL_TEXTURE_EXTERNAL_OES);
1355b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian    glDisable(GL_TEXTURE_2D);
1356f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    glDisable(GL_BLEND);
1357b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian    glColor4f(0,0,0,0);
1358f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian
135955801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian    const int32_t height = hw->getHeight();
1360f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    Region::const_iterator it = region.begin();
1361f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    Region::const_iterator const end = region.end();
1362f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    while (it != end) {
1363f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        const Rect& r = *it++;
136455801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian        GLfloat vertices[][2] = {
136555801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian                { r.left,  height - r.top },
136655801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian                { r.left,  height - r.bottom },
136755801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian                { r.right, height - r.bottom },
136855801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian                { r.right, height - r.top }
136955801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian        };
137055801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian        glVertexPointer(2, GL_FLOAT, 0, vertices);
1371f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1372f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    }
1373edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1374edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
137596f0819f81293076e652792794a961543e6750d7Mathias Agopianssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
137696f0819f81293076e652792794a961543e6750d7Mathias Agopian        const sp<LayerBaseClient>& lbc)
13771b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
137896f0819f81293076e652792794a961543e6750d7Mathias Agopian    // attach this layer to the client
13794f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    size_t name = client->attachLayer(lbc);
13804f113740180b6512b43723c4728f262882dc9b45Mathias Agopian
138196f0819f81293076e652792794a961543e6750d7Mathias Agopian    // add this layer to the current state list
1382921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    Mutex::Autolock _l(mStateLock);
1383921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    mCurrentState.layersSortedByZ.add(lbc);
138496f0819f81293076e652792794a961543e6750d7Mathias Agopian
13854f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    return ssize_t(name);
138696f0819f81293076e652792794a961543e6750d7Mathias Agopian}
138796f0819f81293076e652792794a961543e6750d7Mathias Agopian
138896f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer)
138996f0819f81293076e652792794a961543e6750d7Mathias Agopian{
139096f0819f81293076e652792794a961543e6750d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
139196f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = purgatorizeLayer_l(layer);
139296f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR)
13933559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        setTransactionFlags(eTransactionNeeded);
139496f0819f81293076e652792794a961543e6750d7Mathias Agopian    return err;
1395edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1396edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1397076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase)
1398edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1399edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase);
1400edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (index >= 0) {
1401076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved = true;
1402edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
1403edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
14043d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    return status_t(index);
1405edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1406edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
14079a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase)
14089a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
140976cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    // First add the layer to the purgatory list, which makes sure it won't
141076cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    // go away, then remove it from the main list (through a transaction).
14119a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    ssize_t err = removeLayer_l(layerBase);
141276cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    if (err >= 0) {
141376cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian        mLayerPurgatory.add(layerBase);
141476cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    }
14158c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian
14162f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall    mLayersPendingRemoval.push(layerBase);
14170b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian
14183d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // it's possible that we don't find a layer, because it might
14193d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // have been destroyed already -- this is not technically an error
142096f0819f81293076e652792794a961543e6750d7Mathias Agopian    // from the user because there is a race between Client::destroySurface(),
142196f0819f81293076e652792794a961543e6750d7Mathias Agopian    // ~Client() and ~ISurface().
14229a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err;
14239a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
14249a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
1425dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopianuint32_t SurfaceFlinger::peekTransactionFlags(uint32_t flags)
1426dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian{
1427dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian    return android_atomic_release_load(&mTransactionFlags);
1428dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian}
1429dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian
1430edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags)
1431edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1432edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return android_atomic_and(~flags, &mTransactionFlags) & flags;
1433edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1434edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1435bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags)
1436edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1437edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t old = android_atomic_or(flags, &mTransactionFlags);
1438edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((old & flags)==0) { // wake the server up
143999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        signalTransaction();
1440edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1441edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return old;
1442edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1443edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
14448b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopianvoid SurfaceFlinger::setTransactionState(
14458b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        const Vector<ComposerState>& state,
14468b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        const Vector<DisplayState>& displays,
14478b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        uint32_t flags)
14488b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian{
1449698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
145028378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    uint32_t transactionFlags = 0;
1451e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
1452e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    size_t count = displays.size();
1453e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
1454e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const DisplayState& s(displays[i]);
1455e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        transactionFlags |= setDisplayStateLocked(s);
1456b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis    }
1457b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis
1458e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    count = state.size();
1459698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
1460698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const ComposerState& s(state[i]);
1461698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        sp<Client> client( static_cast<Client *>(s.client.get()) );
146228378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        transactionFlags |= setClientStateLocked(client, s.state);
1463698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    }
1464386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian
146528378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    if (transactionFlags) {
1466386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // this triggers the transaction
146728378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        setTransactionFlags(transactionFlags);
1468698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian
1469386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // if this is a synchronous transaction, wait for it to take effect
1470386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // before returning.
1471386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        if (flags & eSynchronous) {
1472386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            mTransationPending = true;
1473386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        }
1474386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        while (mTransationPending) {
1475386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
1476386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            if (CC_UNLIKELY(err != NO_ERROR)) {
1477386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                // just in case something goes wrong in SF, return to the
1478386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                // called after a few seconds.
147932397c1cd3327905173b36baa6fd1c579bc328ffSteve Block                ALOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!");
1480386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                mTransationPending = false;
1481386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                break;
1482386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            }
1483cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        }
1484edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1485edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1486edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1487e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setDisplayStateLocked(const DisplayState& s)
1488e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{
1489e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    uint32_t flags = 0;
1490e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    DisplayDeviceState& disp(mCurrentState.displays.editValueFor(s.token));
14913ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    if (disp.isValid()) {
1492e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const uint32_t what = s.what;
1493e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & DisplayState::eSurfaceChanged) {
1494e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.surface->asBinder() != s.surface->asBinder()) {
1495e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.surface = s.surface;
1496e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
1497e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1498e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1499e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & DisplayState::eLayerStackChanged) {
1500e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.layerStack != s.layerStack) {
1501e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.layerStack = s.layerStack;
1502e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
1503e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1504e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1505818b46058aa3006e1d3c178abd36d4f10823f5d9Mathias Agopian        if (what & DisplayState::eOrientationChanged) {
1506e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.orientation != s.orientation) {
1507e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.orientation = s.orientation;
1508e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
1509e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1510818b46058aa3006e1d3c178abd36d4f10823f5d9Mathias Agopian        }
1511818b46058aa3006e1d3c178abd36d4f10823f5d9Mathias Agopian        if (what & DisplayState::eFrameChanged) {
1512e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.frame != s.frame) {
1513e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.frame = s.frame;
1514e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
1515e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1516818b46058aa3006e1d3c178abd36d4f10823f5d9Mathias Agopian        }
1517818b46058aa3006e1d3c178abd36d4f10823f5d9Mathias Agopian        if (what & DisplayState::eViewportChanged) {
1518e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.viewport != s.viewport) {
1519e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.viewport = s.viewport;
1520e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
1521e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1522e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1523e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
1524e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return flags;
1525e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
1526e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
1527e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setClientStateLocked(
1528e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const sp<Client>& client,
1529e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const layer_state_t& s)
1530e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{
1531e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    uint32_t flags = 0;
1532e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    sp<LayerBaseClient> layer(client->getLayerUser(s.surface));
1533e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    if (layer != 0) {
1534e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const uint32_t what = s.what;
1535e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::ePositionChanged) {
1536e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setPosition(s.x, s.y))
1537e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1538e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1539e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eLayerChanged) {
1540e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            // NOTE: index needs to be calculated before we update the state
1541e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
1542e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setLayer(s.z)) {
1543e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.removeAt(idx);
1544e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.add(layer);
1545e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // we need traversal (state changed)
1546e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // AND transaction (list changed)
1547e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTransactionNeeded|eTraversalNeeded;
1548e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1549e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1550e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eSizeChanged) {
1551e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setSize(s.w, s.h)) {
1552e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1553e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1554e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1555e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eAlphaChanged) {
1556e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f)))
1557e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1558e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1559e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eMatrixChanged) {
1560e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setMatrix(s.matrix))
1561e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1562e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1563e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eTransparentRegionChanged) {
1564e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setTransparentRegionHint(s.transparentRegion))
1565e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1566e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1567e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eVisibilityChanged) {
1568e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setFlags(s.flags, s.mask))
1569e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1570e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1571e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eCropChanged) {
1572e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setCrop(s.crop))
1573e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1574e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1575e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eLayerStackChanged) {
1576e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            // NOTE: index needs to be calculated before we update the state
1577e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
1578e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setLayerStack(s.layerStack)) {
1579e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.removeAt(idx);
1580e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.add(layer);
1581e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // we need traversal (state changed)
1582e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // AND transaction (list changed)
1583e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTransactionNeeded|eTraversalNeeded;
1584e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1585e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1586e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
1587e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return flags;
1588e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
1589e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
1590921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopiansp<ISurface> SurfaceFlinger::createLayer(
15910ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        ISurfaceComposerClient::surface_data_t* params,
15920ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const String8& name,
15930ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const sp<Client>& client,
15943ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian       uint32_t w, uint32_t h, PixelFormat format,
1595edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t flags)
1596edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1597076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBaseClient> layer;
1598a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    sp<ISurface> surfaceHandle;
15996e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian
16006e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    if (int32_t(w|h) < 0) {
1601921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        ALOGE("createLayer() failed, w or h is negative (w=%d, h=%d)",
16026e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian                int(w), int(h));
16036e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian        return surfaceHandle;
16046e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    }
16058b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
1606921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    //ALOGD("createLayer for (%d x %d), name=%s", w, h, name.string());
16073165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian    switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {
16083165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        case ISurfaceComposerClient::eFXSurfaceNormal:
16093ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian            layer = createNormalLayer(client, w, h, flags, format);
1610edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
16113165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        case ISurfaceComposerClient::eFXSurfaceBlur:
16123165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        case ISurfaceComposerClient::eFXSurfaceDim:
16133ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian            layer = createDimLayer(client, w, h, flags);
1614edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
16153165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        case ISurfaceComposerClient::eFXSurfaceScreenshot:
16163ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian            layer = createScreenshotLayer(client, w, h, flags);
1617118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian            break;
1618edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1619edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1620076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (layer != 0) {
162196f0819f81293076e652792794a961543e6750d7Mathias Agopian        layer->initStates(w, h, flags);
1622285dbde2e0cd0057be070ded3be8f5f453147edcMathias Agopian        layer->setName(name);
162396f0819f81293076e652792794a961543e6750d7Mathias Agopian        ssize_t token = addClientLayer(client, layer);
1624edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        surfaceHandle = layer->getSurface();
16258b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber        if (surfaceHandle != 0) {
162696f0819f81293076e652792794a961543e6750d7Mathias Agopian            params->token = token;
1627a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            params->identity = layer->getIdentity();
16281c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        }
162996f0819f81293076e652792794a961543e6750d7Mathias Agopian        setTransactionFlags(eTransactionNeeded);
1630edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1631edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1632edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return surfaceHandle;
1633edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1634edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1635921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopiansp<Layer> SurfaceFlinger::createNormalLayer(
16363ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian        const sp<Client>& client,
163796f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags,
16381c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        PixelFormat& format)
1639edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1640edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize the surfaces
164192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    switch (format) {
1642edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSPARENT:
1643edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSLUCENT:
1644edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        format = PIXEL_FORMAT_RGBA_8888;
1645edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1646edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_OPAQUE:
1647a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888
1648a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian        format = PIXEL_FORMAT_RGB_565;
1649a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#else
16508f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian        format = PIXEL_FORMAT_RGBX_8888;
1651a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif
1652edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1653edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1654edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1655a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888
1656a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian    if (format == PIXEL_FORMAT_RGBX_8888)
1657a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian        format = PIXEL_FORMAT_RGBA_8888;
1658a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif
1659a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian
16603ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    sp<Layer> layer = new Layer(this, client);
1661f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian    status_t err = layer->setBuffers(w, h, format, flags);
166299ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten    if (CC_LIKELY(err != NO_ERROR)) {
1663921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        ALOGE("createNormalLayer() failed (%s)", strerror(-err));
1664076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        layer.clear();
1665edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1666edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1667edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1668edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1669921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopiansp<LayerDim> SurfaceFlinger::createDimLayer(
16703ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian        const sp<Client>& client,
167196f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags)
1672edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
16733ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    sp<LayerDim> layer = new LayerDim(this, client);
1674118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    return layer;
1675118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
1676118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
1677921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopiansp<LayerScreenshot> SurfaceFlinger::createScreenshotLayer(
16783ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian        const sp<Client>& client,
1679118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags)
1680118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{
16813ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    sp<LayerScreenshot> layer = new LayerScreenshot(this, client);
1682edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1683edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1684edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1685921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianstatus_t SurfaceFlinger::onLayerRemoved(const sp<Client>& client, SurfaceID sid)
16869a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
16879a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    /*
16889a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     * called by the window manager, when a surface should be marked for
16899a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     * destruction.
16908b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber     *
16910aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * The surface is removed from the current and drawing lists, but placed
16920aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * in the purgatory queue, so it's not destroyed right-away (we need
16930aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * to wait for all client's references to go away first).
16949a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     */
16959a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
169648d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    status_t err = NAME_NOT_FOUND;
16970aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian    Mutex::Autolock _l(mStateLock);
169896f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<LayerBaseClient> layer = client->getLayerUser(sid);
1699b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam
170048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    if (layer != 0) {
170148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        err = purgatorizeLayer_l(layer);
170248d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        if (err == NO_ERROR) {
170313233e067b8f71adc3a0ade5f442265e1f27084bMathias Agopian            setTransactionFlags(eTransactionNeeded);
170448d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        }
17059a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    }
17069a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return err;
17079a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
17089a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
1709921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianstatus_t SurfaceFlinger::onLayerDestroyed(const wp<LayerBaseClient>& layer)
1710edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1711759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian    // called by ~ISurface() when all references are gone
1712ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    status_t err = NO_ERROR;
1713ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    sp<LayerBaseClient> l(layer.promote());
1714ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    if (l != NULL) {
1715ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        Mutex::Autolock _l(mStateLock);
1716ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        err = removeLayer_l(l);
1717ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        if (err == NAME_NOT_FOUND) {
1718ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // The surface wasn't in the current list, which means it was
1719ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // removed already, which means it is in the purgatory,
1720ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // and need to be removed from there.
1721ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            ssize_t idx = mLayerPurgatory.remove(l);
1722e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block            ALOGE_IF(idx < 0,
1723ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian                    "layer=%p is not in the purgatory list", l.get());
1724f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        }
1725e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE_IF(err<0 && err != NAME_NOT_FOUND,
1726ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian                "error removing layer=%p (%s)", l.get(), strerror(-err));
1727ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    }
1728ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    return err;
1729edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1730edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1731b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// ---------------------------------------------------------------------------
1732b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
173313a082e160c2d1d8006b93a555a57035213d568bAndy McFaddenvoid SurfaceFlinger::onInitializeDisplays() {
173413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    // reset screen orientation
173513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    Vector<ComposerState> state;
173613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    Vector<DisplayState> displays;
173713a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    DisplayState d;
173813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    d.what = DisplayState::eOrientationChanged;
17393ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    d.token = mDefaultDisplays[DisplayDevice::DISPLAY_PRIMARY];
174013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    d.orientation = DisplayState::eOrientationDefault;
174113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    displays.add(d);
174213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    setTransactionState(state, displays, 0);
174313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
174413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    // XXX: this should init default device to "unblank" and all other devices to "blank"
174513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    onScreenAcquired();
174613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden}
174713a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
174813a082e160c2d1d8006b93a555a57035213d568bAndy McFaddenvoid SurfaceFlinger::initializeDisplays() {
174913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    class MessageScreenInitialized : public MessageBase {
175013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden        SurfaceFlinger* flinger;
175113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    public:
175213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden        MessageScreenInitialized(SurfaceFlinger* flinger) : flinger(flinger) { }
175313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden        virtual bool handler() {
175413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden            flinger->onInitializeDisplays();
175513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden            return true;
175613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden        }
175713a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    };
175813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    sp<MessageBase> msg = new MessageScreenInitialized(this);
175913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    postMessageAsync(msg);  // we may be called from main thread, use async message
176013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden}
176113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
176213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
1763b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopianvoid SurfaceFlinger::onScreenAcquired() {
17648e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross    ALOGD("Screen about to return, flinger = %p", this);
17654297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    sp<const DisplayDevice> hw(getDefaultDisplayDevice()); // XXX: this should be per DisplayDevice
17668630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    getHwComposer().acquire();
17674297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->acquireScreen();
176822ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian    mEventThread->onScreenAcquired();
176920128300e0cb7f459a60cfbcddb48190ce6545edMathias Agopian    mVisibleRegionsDirty = true;
177020128300e0cb7f459a60cfbcddb48190ce6545edMathias Agopian    repaintEverything();
1771edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1772edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1773b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopianvoid SurfaceFlinger::onScreenReleased() {
17748e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross    ALOGD("About to give-up screen, flinger = %p", this);
17754297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    sp<const DisplayDevice> hw(getDefaultDisplayDevice()); // XXX: this should be per DisplayDevice
17764297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    if (hw->isScreenAcquired()) {
177722ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian        mEventThread->onScreenReleased();
17784297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        hw->releaseScreen();
17798630320433bd15aca239522e54e711ef6372ab07Mathias Agopian        getHwComposer().release();
1780b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        // from this point on, SF will stop drawing
1781b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    }
1782b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian}
1783b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
17848e533069e5721e55cb9768e140e16546c3a4a8b6Colin Crossvoid SurfaceFlinger::unblank() {
1785b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    class MessageScreenAcquired : public MessageBase {
1786b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        SurfaceFlinger* flinger;
1787b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    public:
1788b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        MessageScreenAcquired(SurfaceFlinger* flinger) : flinger(flinger) { }
1789b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        virtual bool handler() {
1790b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            flinger->onScreenAcquired();
1791b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            return true;
1792b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        }
1793b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    };
1794b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    sp<MessageBase> msg = new MessageScreenAcquired(this);
1795b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    postMessageSync(msg);
1796edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1797edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
17988e533069e5721e55cb9768e140e16546c3a4a8b6Colin Crossvoid SurfaceFlinger::blank() {
1799b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    class MessageScreenReleased : public MessageBase {
1800b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        SurfaceFlinger* flinger;
1801b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    public:
1802b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        MessageScreenReleased(SurfaceFlinger* flinger) : flinger(flinger) { }
1803b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        virtual bool handler() {
1804b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            flinger->onScreenReleased();
1805b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            return true;
1806b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        }
1807b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    };
1808b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    sp<MessageBase> msg = new MessageScreenReleased(this);
1809b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    postMessageSync(msg);
1810b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian}
1811b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
1812b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// ---------------------------------------------------------------------------
1813b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
1814edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
1815edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
18161d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling    const size_t SIZE = 4096;
1817edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char buffer[SIZE];
1818edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    String8 result;
181999b49840d309727678b77403d6cc9f920111623fMathias Agopian
182099b49840d309727678b77403d6cc9f920111623fMathias Agopian    if (!PermissionCache::checkCallingPermission(sDump)) {
1821edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        snprintf(buffer, SIZE, "Permission Denial: "
1822edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                "can't dump SurfaceFlinger from pid=%d, uid=%d\n",
1823edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                IPCThreadState::self()->getCallingPid(),
1824edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                IPCThreadState::self()->getCallingUid());
1825edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        result.append(buffer);
1826edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
18279795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // Try to get the main lock, but don't insist if we can't
18289795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // (this would indicate SF is stuck, but we want to be able to
18299795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // print something in dumpsys).
18309795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        int retry = 3;
18319795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        while (mStateLock.tryLock()<0 && --retry>=0) {
18329795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            usleep(1000000);
18339795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
18349795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const bool locked(retry >= 0);
18359795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (!locked) {
18368b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber            snprintf(buffer, SIZE,
18379795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "SurfaceFlinger appears to be unresponsive, "
18389795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "dumping anyways (no locks held)\n");
18399795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            result.append(buffer);
18409795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
18419795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
184282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        bool dumpAll = true;
184382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        size_t index = 0;
184425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        size_t numArgs = args.size();
184525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        if (numArgs) {
184625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
184725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--list"))) {
184825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                index++;
184925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                listLayersLocked(args, index, result, buffer, SIZE);
185035aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
185125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            }
185225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
185325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
185425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--latency"))) {
185582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                index++;
185682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                dumpStatsLocked(args, index, result, buffer, SIZE);
185735aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
185882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            }
185925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
186025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
186125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--latency-clear"))) {
186225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                index++;
186325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                clearStatsLocked(args, index, result, buffer, SIZE);
186435aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
186525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            }
1866edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
18671b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
186882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (dumpAll) {
186982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            dumpAllLocked(result, buffer, SIZE);
187082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
187148b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
187282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (locked) {
187382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mStateLock.unlock();
187448b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        }
187582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
187682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    write(fd, result.string(), result.size());
187782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    return NO_ERROR;
187882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
187948b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
188025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::listLayersLocked(const Vector<String16>& args, size_t& index,
188125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        String8& result, char* buffer, size_t SIZE) const
188225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
188325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
188425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const size_t count = currentLayers.size();
188525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
188625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
188725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        snprintf(buffer, SIZE, "%s\n", layer->getName().string());
188825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        result.append(buffer);
188925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
189025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
189125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
189282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index,
189382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        String8& result, char* buffer, size_t SIZE) const
189482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
189582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    String8 name;
189682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    if (index < args.size()) {
189782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        name = String8(args[index]);
189882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        index++;
189982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
190048b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
190182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
190282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const size_t count = currentLayers.size();
190382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    for (size_t i=0 ; i<count ; i++) {
190482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
190582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (name.isEmpty()) {
190682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            snprintf(buffer, SIZE, "%s\n", layer->getName().string());
190782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            result.append(buffer);
190882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
190982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (name.isEmpty() || (name == layer->getName())) {
191082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            layer->dumpStats(result, buffer, SIZE);
191182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
191282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
191382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
1914ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian
191525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& index,
191625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        String8& result, char* buffer, size_t SIZE) const
191725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
191825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    String8 name;
191925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    if (index < args.size()) {
192025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        name = String8(args[index]);
192125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        index++;
192225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
192325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
192425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
192525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const size_t count = currentLayers.size();
192625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
192725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
192825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        if (name.isEmpty() || (name == layer->getName())) {
192925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            layer->clearStats();
193025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        }
193125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
193225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
193325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
193482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpAllLocked(
193582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        String8& result, char* buffer, size_t SIZE) const
193682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
193782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    // figure out if we're stuck somewhere
193882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t now = systemTime();
193982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t inSwapBuffers(mDebugInSwapBuffers);
194082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t inTransaction(mDebugInTransaction);
194182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0;
194282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0;
1943bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
194482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
194582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump the visible layer list
194682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
194782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
194882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const size_t count = currentLayers.size();
194982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "Visible layers (count = %d)\n", count);
195082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
195182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    for (size_t i=0 ; i<count ; i++) {
195282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
195382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        layer->dump(result, buffer, SIZE);
195482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
1955bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
195682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
195782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump the layers in the purgatory
195882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
1959ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian
196082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const size_t purgatorySize = mLayerPurgatory.size();
196182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "Purgatory state (%d entries)\n", purgatorySize);
196282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
196382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    for (size_t i=0 ; i<purgatorySize ; i++) {
196482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
196582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        layer->shortDump(result, buffer, SIZE);
196682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
19671b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
196882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
19695f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian     * Dump Display state
19705f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian     */
19715f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian
19725f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
19735f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        const sp<const DisplayDevice>& hw(mDisplays[dpy]);
19745f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        snprintf(buffer, SIZE,
19755f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian                "+ DisplayDevice[%u]\n"
19765f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian                "   id=%x, layerStack=%u, (%4dx%4d), orient=%2d, tr=%08x, "
19775f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian                "flips=%u, secure=%d, numLayers=%u\n",
19785f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian                dpy,
19793ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian                hw->getDisplayType(), hw->getLayerStack(),
19805f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian                hw->getWidth(), hw->getHeight(),
19815f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian                hw->getOrientation(), hw->getTransform().getType(),
19825f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian                hw->getPageFlipCount(),
19835f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian                hw->getSecureLayerVisible(),
19845f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian                hw->getVisibleLayersSortedByZ().size());
19855f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        result.append(buffer);
19865f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    }
19875f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian
19885f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    /*
198982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump SurfaceFlinger global state
199082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
19911b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
199282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "SurfaceFlinger global state:\n");
199382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
19941b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
1995888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian    HWComposer& hwc(getHwComposer());
19964297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    sp<const DisplayDevice> hw(getDefaultDisplayDevice());
199782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const GLExtensions& extensions(GLExtensions::getInstance());
199882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "GLES: %s, %s, %s\n",
199982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            extensions.getVendor(),
200082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            extensions.getRenderer(),
200182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            extensions.getVersion());
200282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
2003d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
200482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "EGL : %s\n",
2005d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian            eglQueryString(mEGLDisplay, EGL_VERSION_HW_ANDROID));
200682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
200773d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian
200882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "EXTS: %s\n", extensions.getExtension());
200982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
20109795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
20114297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->undefinedRegion.dump(result, "undefinedRegion");
201282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE,
201382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  orientation=%d, canDraw=%d\n",
20144297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->getOrientation(), hw->canDraw());
201582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
201682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE,
201782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  last eglSwapBuffers() time: %f us\n"
201882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  last transaction time     : %f us\n"
2019c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian            "  transaction-flags         : %08x\n"
202082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  refresh-rate              : %f fps\n"
202182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  x-dpi                     : %f\n"
20228b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            "  y-dpi                     : %f\n",
202382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mLastSwapBufferTime/1000.0,
202482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mLastTransactionTime/1000.0,
2025c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian            mTransactionFlags,
2026888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian            1e9 / hwc.getRefreshPeriod(),
20278b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            hwc.getDpiX(),
20288b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            hwc.getDpiY());
202982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
203082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
203182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "  eglSwapBuffers time: %f us\n",
203282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            inSwapBuffersDuration/1000.0);
203382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
203482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
203582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "  transaction time: %f us\n",
203682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            inTransactionDuration/1000.0);
203782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
203882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
203982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
204082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * VSYNC state
204182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
204282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    mEventThread->dump(result, buffer, SIZE);
204382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
204482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
204582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump HWComposer state
204682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
204782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "h/w composer state:\n");
204882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
204982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "  h/w composer %s and %s\n",
205082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            hwc.initCheck()==NO_ERROR ? "present" : "not present",
205182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                    (mDebugDisableHWC || mDebugRegion) ? "disabled" : "enabled");
205282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
20534297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hwc.dump(result, buffer, SIZE, hw->getVisibleLayersSortedByZ());
205482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
205582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
205682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump gralloc state
205782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
205882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
205982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    alloc.dump(result);
20604297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->dump(result);
2061edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2062edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2063edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::onTransact(
2064edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
2065edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2066edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (code) {
2067edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case CREATE_CONNECTION:
2068698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        case SET_TRANSACTION_STATE:
2069edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case BOOT_FINISHED:
20708e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross        case BLANK:
20718e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross        case UNBLANK:
2072edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        {
2073edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // codes that require permission check
2074edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            IPCThreadState* ipc = IPCThreadState::self();
2075edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int pid = ipc->getCallingPid();
2076a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian            const int uid = ipc->getCallingUid();
207799b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
207899b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) {
2079e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block                ALOGE("Permission Denial: "
2080375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                        "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
2081375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                return PERMISSION_DENIED;
2082edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
20831b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
20841b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
20851b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        case CAPTURE_SCREEN:
20861b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
20871b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            // codes that require permission check
20881b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
20891b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int pid = ipc->getCallingPid();
20901b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int uid = ipc->getCallingUid();
209199b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
209299b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) {
2093e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block                ALOGE("Permission Denial: "
20941b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                        "can't read framebuffer pid=%d, uid=%d", pid, uid);
20951b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                return PERMISSION_DENIED;
20961b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            }
20971b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
2098edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
2099edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
21001b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
2101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
2102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
2103b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        CHECK_INTERFACE(ISurfaceComposer, data, reply);
210499ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten        if (CC_UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) {
2105375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
2106375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int pid = ipc->getCallingPid();
2107375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int uid = ipc->getCallingUid();
2108e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block            ALOGE("Permission Denial: "
2109375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                    "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
2110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return PERMISSION_DENIED;
2111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
2112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int n;
2113edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        switch (code) {
211401b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian            case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE
211535b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian            case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE
2116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
2117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1002:  // SHOW_UPDATES
2118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                n = data.readInt32();
2119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDebugRegion = n ? n : (mDebugRegion ? 0 : 1);
212053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
212153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
2122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
2123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1004:{ // repaint everything
212453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
2125cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
2126cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            }
2127cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            case 1005:{ // force transaction
2128e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                setTransactionFlags(
2129e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        eTransactionNeeded|
2130e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        eDisplayTransactionNeeded|
2131e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        eTraversalNeeded);
2132cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
2133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
21344d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            case 1006:{ // send empty update
21354d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian                signalRefresh();
21364d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian                return NO_ERROR;
21374d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            }
213853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian            case 1008:  // toggle use of hw composer
213953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                n = data.readInt32();
214053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                mDebugDisableHWC = n ? 1 : 0;
214153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
214253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
214353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                return NO_ERROR;
2144a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian            case 1009:  // toggle use of transform hint
2145a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                n = data.readInt32();
2146a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                mDebugDisableTransformHint = n ? 1 : 0;
2147a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                invalidateHwcGeometry();
2148a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                repaintEverything();
2149a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                return NO_ERROR;
2150edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1010:  // interrogate.
215101b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian                reply->writeInt32(0);
2152edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(0);
2153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(mDebugRegion);
2154b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                reply->writeInt32(0);
215512839bee29bdcc65731b4d42029cc59e2320c5c4Dianne Hackborn                reply->writeInt32(mDebugDisableHWC);
2156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
2157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1013: {
2158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                Mutex::Autolock _l(mStateLock);
21594297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                sp<const DisplayDevice> hw(getDefaultDisplayDevice());
21604297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                reply->writeInt32(hw->getPageFlipCount());
2161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
2162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return NO_ERROR;
2163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
2164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return err;
2166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
216853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopianvoid SurfaceFlinger::repaintEverything() {
216987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    android_atomic_or(1, &mRepaintEverything);
217099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    signalTransaction();
217153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian}
217253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian
217359119e658a12279e8fff508f8773843de2d90917Mathias Agopian// ---------------------------------------------------------------------------
217459119e658a12279e8fff508f8773843de2d90917Mathias Agopian
21753ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopianstatus_t SurfaceFlinger::renderScreenToTexture(uint32_t layerStack,
2176118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        GLuint* textureName, GLfloat* uOut, GLfloat* vOut)
2177118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{
2178118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    Mutex::Autolock _l(mStateLock);
21793ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    return renderScreenToTextureLocked(layerStack, textureName, uOut, vOut);
2180118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
2181118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
21823ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopianstatus_t SurfaceFlinger::renderScreenToTextureLocked(uint32_t layerStack,
21839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        GLuint* textureName, GLfloat* uOut, GLfloat* vOut)
218459119e658a12279e8fff508f8773843de2d90917Mathias Agopian{
218522ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian    ATRACE_CALL();
218622ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian
218759119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
218859119e658a12279e8fff508f8773843de2d90917Mathias Agopian        return INVALID_OPERATION;
218959119e658a12279e8fff508f8773843de2d90917Mathias Agopian
219059119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // get screen geometry
21913ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    // FIXME: figure out what it means to have a screenshot texture w/ multi-display
21923ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    sp<const DisplayDevice> hw(getDefaultDisplayDevice());
21934297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const uint32_t hw_w = hw->getWidth();
21944297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const uint32_t hw_h = hw->getHeight();
219559119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLfloat u = 1;
219659119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLfloat v = 1;
219759119e658a12279e8fff508f8773843de2d90917Mathias Agopian
219859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // make sure to clear all GL error flags
219959119e658a12279e8fff508f8773843de2d90917Mathias Agopian    while ( glGetError() != GL_NO_ERROR ) ;
220059119e658a12279e8fff508f8773843de2d90917Mathias Agopian
220159119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // create a FBO
220259119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLuint name, tname;
220359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glGenTextures(1, &tname);
220459119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
2205a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2206a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
22079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
22089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            hw_w, hw_h, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
220959119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (glGetError() != GL_NO_ERROR) {
2210015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian        while ( glGetError() != GL_NO_ERROR ) ;
221159119e658a12279e8fff508f8773843de2d90917Mathias Agopian        GLint tw = (2 << (31 - clz(hw_w)));
221259119e658a12279e8fff508f8773843de2d90917Mathias Agopian        GLint th = (2 << (31 - clz(hw_h)));
22139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
22149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian                tw, th, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
221559119e658a12279e8fff508f8773843de2d90917Mathias Agopian        u = GLfloat(hw_w) / tw;
221659119e658a12279e8fff508f8773843de2d90917Mathias Agopian        v = GLfloat(hw_h) / th;
221759119e658a12279e8fff508f8773843de2d90917Mathias Agopian    }
221859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glGenFramebuffersOES(1, &name);
221959119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
22209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES,
22219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0);
222259119e658a12279e8fff508f8773843de2d90917Mathias Agopian
22239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // redraw the screen entirely...
2224c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_EXTERNAL_OES);
2225c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_2D);
22269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glClearColor(0,0,0,1);
22279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glClear(GL_COLOR_BUFFER_BIT);
2228a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glMatrixMode(GL_MODELVIEW);
2229a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glLoadIdentity();
22304297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const Vector< sp<LayerBase> >& layers(hw->getVisibleLayersSortedByZ());
22319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const size_t count = layers.size();
22329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (size_t i=0 ; i<count ; ++i) {
22339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
2234fcb239d3dac8bc80f28177f1951611c1d43286ffMathias Agopian        layer->draw(hw);
22359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
223659119e658a12279e8fff508f8773843de2d90917Mathias Agopian
22374297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->compositionComplete();
2238118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
22399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // back to main framebuffer
22409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
22419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDeleteFramebuffersOES(1, &name);
224259119e658a12279e8fff508f8773843de2d90917Mathias Agopian
22439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *textureName = tname;
22449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *uOut = u;
22459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *vOut = v;
22469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
22479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
224859119e658a12279e8fff508f8773843de2d90917Mathias Agopian
22499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// ---------------------------------------------------------------------------
22509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22519d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brownstatus_t SurfaceFlinger::captureScreenImplLocked(const sp<IBinder>& display,
225274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        sp<IMemoryHeap>* heap,
225374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t* w, uint32_t* h, PixelFormat* f,
2254bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t sw, uint32_t sh,
2255bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ, uint32_t maxLayerZ)
225674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{
2257fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian    ATRACE_CALL();
2258fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian
225974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    status_t result = PERMISSION_DENIED;
226074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
22613b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject()) {
226274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return INVALID_OPERATION;
22633b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
226474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
226574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // get screen geometry
22663ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    sp<const DisplayDevice> hw(getDisplayDevice(display));
22674297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const uint32_t hw_w = hw->getWidth();
22684297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const uint32_t hw_h = hw->getHeight();
226974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
22703b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    // if we have secure windows on this display, never allow the screen capture
22714297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    if (hw->getSecureLayerVisible()) {
2272ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian        ALOGW("FB is protected: PERMISSION_DENIED");
22733b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        return PERMISSION_DENIED;
22743b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
22753b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
22763b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    if ((sw > hw_w) || (sh > hw_h)) {
2277ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian        ALOGE("size mismatch (%d, %d) > (%d, %d)", sw, sh, hw_w, hw_h);
227874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return BAD_VALUE;
22793b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
228074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
228174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    sw = (!sw) ? hw_w : sw;
228274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    sh = (!sh) ? hw_h : sh;
228374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const size_t size = sw * sh * 4;
2284fcb239d3dac8bc80f28177f1951611c1d43286ffMathias Agopian    const bool filtering = sw != hw_w || sh != hw_h;
228574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
2286ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian//    ALOGD("screenshot: sw=%d, sh=%d, minZ=%d, maxZ=%d",
2287ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian//            sw, sh, minLayerZ, maxLayerZ);
2288c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
228974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // make sure to clear all GL error flags
229074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    while ( glGetError() != GL_NO_ERROR ) ;
229174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
229274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // create a FBO
229374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    GLuint name, tname;
229474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glGenRenderbuffersOES(1, &tname);
229574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindRenderbufferOES(GL_RENDERBUFFER_OES, tname);
229674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA8_OES, sw, sh);
2297fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian
229874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glGenFramebuffersOES(1, &name);
229974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
230074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES,
230174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, tname);
230274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
230374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
2304c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
230574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    if (status == GL_FRAMEBUFFER_COMPLETE_OES) {
230674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
230774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // invert everything, b/c glReadPixel() below will invert the FB
230874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glViewport(0, 0, sw, sh);
230974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_PROJECTION);
231074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glPushMatrix();
231174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glLoadIdentity();
2312ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian        glOrthof(0, hw_w, hw_h, 0, 0, 1);
231374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_MODELVIEW);
231474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
231574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // redraw the screen entirely...
231674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glClearColor(0,0,0,1);
231774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
2318f653b897a449e10d6cbfb6e0812f7b0bb02d6482Mathias Agopian
23193ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian        const Vector< sp<LayerBase> >& layers(hw->getVisibleLayersSortedByZ());
23209575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        const size_t count = layers.size();
232174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        for (size_t i=0 ; i<count ; ++i) {
232274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            const sp<LayerBase>& layer(layers[i]);
23233ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian            const uint32_t z = layer->drawingState().z;
23243ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian            if (z >= minLayerZ && z <= maxLayerZ) {
23253ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian                if (filtering) layer->setFiltering(true);
23263ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian                layer->draw(hw);
23273ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian                if (filtering) layer->setFiltering(false);
2328bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian            }
232974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        }
233074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
233174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // check for errors and return screen capture
233274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        if (glGetError() != GL_NO_ERROR) {
233374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // error while rendering
233474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            result = INVALID_OPERATION;
233574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        } else {
233674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // allocate shared memory large enough to hold the
233774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // screen capture
233874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            sp<MemoryHeapBase> base(
233974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    new MemoryHeapBase(size, 0, "screen-capture") );
234074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            void* const ptr = base->getBase();
234174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            if (ptr) {
234274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                // capture the screen with glReadPixels()
2343fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian                ScopedTrace _t(ATRACE_TAG, "glReadPixels");
234474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                glReadPixels(0, 0, sw, sh, GL_RGBA, GL_UNSIGNED_BYTE, ptr);
234574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                if (glGetError() == GL_NO_ERROR) {
234674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *heap = base;
234774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *w = sw;
234874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *h = sh;
234974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *f = PIXEL_FORMAT_RGBA_8888;
235074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    result = NO_ERROR;
235174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                }
235274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            } else {
235374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                result = NO_MEMORY;
235474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            }
235574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        }
235674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glViewport(0, 0, hw_w, hw_h);
235774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_PROJECTION);
235874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glPopMatrix();
235974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_MODELVIEW);
236074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    } else {
236174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        result = BAD_VALUE;
236274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    }
236374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
236474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // release FBO resources
236574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
236674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glDeleteRenderbuffersOES(1, &tname);
236774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glDeleteFramebuffersOES(1, &name);
2368e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian
23694297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->compositionComplete();
2370e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian
2371ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian//    ALOGD("screenshot: result = %s", result<0 ? strerror(result) : "OK");
2372c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
237374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    return result;
237474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian}
237574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
237674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
23779d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brownstatus_t SurfaceFlinger::captureScreen(const sp<IBinder>& display,
23781b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        sp<IMemoryHeap>* heap,
237974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t* width, uint32_t* height, PixelFormat* format,
2380bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t sw, uint32_t sh,
2381bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ, uint32_t maxLayerZ)
23821b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian{
23839d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown    if (CC_UNLIKELY(display == 0))
23841b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        return BAD_VALUE;
23851b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
23861b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
23871b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        return INVALID_OPERATION;
23881b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
23891b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    class MessageCaptureScreen : public MessageBase {
23901b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        SurfaceFlinger* flinger;
23919d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown        sp<IBinder> display;
23921b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        sp<IMemoryHeap>* heap;
23931b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        uint32_t* w;
23941b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        uint32_t* h;
23951b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        PixelFormat* f;
239674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t sw;
239774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t sh;
2398bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ;
2399bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t maxLayerZ;
24001b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        status_t result;
24011b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    public:
24029d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown        MessageCaptureScreen(SurfaceFlinger* flinger, const sp<IBinder>& display,
240374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                sp<IMemoryHeap>* heap, uint32_t* w, uint32_t* h, PixelFormat* f,
2404bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                uint32_t sw, uint32_t sh,
2405bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                uint32_t minLayerZ, uint32_t maxLayerZ)
24069d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown            : flinger(flinger), display(display),
2407bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              heap(heap), w(w), h(h), f(f), sw(sw), sh(sh),
2408bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              minLayerZ(minLayerZ), maxLayerZ(maxLayerZ),
2409bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              result(PERMISSION_DENIED)
24101b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
24111b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
24121b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        status_t getResult() const {
24131b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            return result;
24141b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
24151b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        virtual bool handler() {
24161b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
24179d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown            result = flinger->captureScreenImplLocked(display,
2418bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                    heap, w, h, f, sw, sh, minLayerZ, maxLayerZ);
24191b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            return true;
24201b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
24211b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    };
24221b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
24231b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    sp<MessageBase> msg = new MessageCaptureScreen(this,
24249d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown            display, heap, width, height, format, sw, sh, minLayerZ, maxLayerZ);
24251b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    status_t res = postMessageSync(msg);
24261b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    if (res == NO_ERROR) {
24271b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        res = static_cast<MessageCaptureScreen*>( msg.get() )->getResult();
24281b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    }
24291b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    return res;
24301b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian}
24311b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
24321b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// ---------------------------------------------------------------------------
24331b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
2434921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::LayerVector::LayerVector() {
2435921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
2436921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
2437921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::LayerVector::LayerVector(const LayerVector& rhs)
2438921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    : SortedVector<sp<LayerBase> >(rhs) {
2439921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
2440921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
2441921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianint SurfaceFlinger::LayerVector::do_compare(const void* lhs,
2442921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    const void* rhs) const
2443edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2444be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    // sort layers per layer-stack, then by z-order and finally by sequence
2445921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    const sp<LayerBase>& l(*reinterpret_cast<const sp<LayerBase>*>(lhs));
2446921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    const sp<LayerBase>& r(*reinterpret_cast<const sp<LayerBase>*>(rhs));
2447be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian
2448be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    uint32_t ls = l->currentState().layerStack;
2449be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    uint32_t rs = r->currentState().layerStack;
2450be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    if (ls != rs)
2451be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian        return ls - rs;
2452be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian
2453921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    uint32_t lz = l->currentState().z;
2454921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    uint32_t rz = r->currentState().z;
2455be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    if (lz != rz)
2456be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian        return lz - rz;
2457be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian
2458be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    return l->sequence - r->sequence;
2459921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
2460921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
2461921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian// ---------------------------------------------------------------------------
2462921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
24633ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias AgopianSurfaceFlinger::DisplayDeviceState::DisplayDeviceState()
24643ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    : type(DisplayDevice::DISPLAY_ID_INVALID) {
2465e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
2466e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
24673ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias AgopianSurfaceFlinger::DisplayDeviceState::DisplayDeviceState(DisplayDevice::DisplayType type)
24683ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    : type(type), layerStack(0), orientation(0) {
2469b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
24707303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
2471b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// ---------------------------------------------------------------------------
247296f0819f81293076e652792794a961543e6750d7Mathias Agopian
24739a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::GraphicBufferAlloc() {}
24749a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
24759a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::~GraphicBufferAlloc() {}
24769a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
24779a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h,
2478d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        PixelFormat format, uint32_t usage, status_t* error) {
24799a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(w, h, format, usage));
24809a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    status_t err = graphicBuffer->initCheck();
2481d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian    *error = err;
2482a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (err != 0 || graphicBuffer->handle == 0) {
2483d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        if (err == NO_MEMORY) {
2484d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian            GraphicBuffer::dumpAllocationsToSystemLog();
2485d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        }
2486e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE("GraphicBufferAlloc::createGraphicBuffer(w=%d, h=%d) "
2487a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian             "failed (%s), handle=%p",
2488a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                w, h, strerror(-err), graphicBuffer->handle);
24899a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis        return 0;
24909a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    }
24919a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    return graphicBuffer;
24929a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis}
24939a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
24949a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis// ---------------------------------------------------------------------------
24959a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
2496edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
2497