SurfaceFlinger.cpp revision ce3a0a541c3dde1330551bd7a048cd9d92335c00
1edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/*
2edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
3edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
4edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * you may not use this file except in compliance with the License.
6edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * You may obtain a copy of the License at
7edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
8edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
10edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * See the License for the specific language governing permissions and
14edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * limitations under the License.
15edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */
16edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
171c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#define ATRACE_TAG ATRACE_TAG_GRAPHICS
181c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
19edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdint.h>
20921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <sys/types.h>
21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <errno.h>
22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <math.h>
2363f165fd6b86d04be94d4023e845e98560504a96Keun young Park#include <dlfcn.h>
24921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
25921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <EGL/egl.h>
26921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <GLES/gl.h>
27edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
28edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/log.h>
29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/properties.h>
30edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
31c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IPCThreadState.h>
32c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IServiceManager.h>
337303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian#include <binder/MemoryHeapBase.h>
3499b49840d309727678b77403d6cc9f920111623fMathias Agopian#include <binder/PermissionCache.h>
357303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
36c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian#include <ui/DisplayInfo.h>
37c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian
38921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <gui/BitTube.h>
391a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <gui/BufferQueue.h>
401a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <gui/IDisplayEventConnection.h>
41921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <gui/SurfaceTextureClient.h>
42921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
43921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <ui/GraphicBufferAllocator.h>
44921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <ui/PixelFormat.h>
45d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String8.h>
47edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String16.h>
48edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/StopWatch.h>
491c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#include <utils/Trace.h>
50edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
51921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <private/android_filesystem_config.h>
52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
53edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h"
5490ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include "DdmConnection.h"
550f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian#include "DisplayDevice.h"
56db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian#include "Client.h"
57d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian#include "EventThread.h"
581f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian#include "GLExtensions.h"
59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h"
60edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerDim.h"
61118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian#include "LayerScreenshot.h"
62edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h"
63edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
64a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#include "DisplayHardware/FramebufferSurface.h"
65a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian#include "DisplayHardware/HWComposer.h"
66edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
67a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
68bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian#define EGL_VERSION_HW_ANDROID  0x3143
69bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DISPLAY_COUNT       1
71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
73edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
74edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
7599b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sHardwareTest("android.permission.HARDWARE_TEST");
7699b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER");
7799b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER");
7899b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sDump("android.permission.DUMP");
7999b49840d309727678b77403d6cc9f920111623fMathias Agopian
8099b49840d309727678b77403d6cc9f920111623fMathias Agopian// ---------------------------------------------------------------------------
8199b49840d309727678b77403d6cc9f920111623fMathias Agopian
82edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::SurfaceFlinger()
83edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    :   BnSurfaceComposer(), Thread(false),
84edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mTransactionFlags(0),
8528378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        mTransationPending(false),
86076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved(false),
8752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        mRepaintEverything(0),
88edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mBootTime(systemTime()),
89edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mVisibleRegionsDirty(false),
90a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        mHwWorkListDirty(false),
91edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDebugRegion(0),
928afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian        mDebugDDMS(0),
9373d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian        mDebugDisableHWC(0),
94a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian        mDebugDisableTransformHint(0),
959795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInSwapBuffers(0),
969795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastSwapBufferTime(0),
979795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInTransaction(0),
989795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastTransactionTime(0),
995f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        mBootFinished(false)
100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
101a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI("SurfaceFlinger is starting");
102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // debugging stuff...
104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char value[PROPERTY_VALUE_MAX];
1058afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    property_get("debug.sf.showupdates", value, "0");
107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDebugRegion = atoi(value);
1088afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
1098afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    property_get("debug.sf.ddms", value, "0");
1108afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    mDebugDDMS = atoi(value);
1118afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    if (mDebugDDMS) {
11263f165fd6b86d04be94d4023e845e98560504a96Keun young Park        if (!startDdmConnection()) {
11363f165fd6b86d04be94d4023e845e98560504a96Keun young Park            // start failed, and DDMS debugging not enabled
11463f165fd6b86d04be94d4023e845e98560504a96Keun young Park            mDebugDDMS = 0;
11563f165fd6b86d04be94d4023e845e98560504a96Keun young Park        }
1168afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    }
117c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    ALOGI_IF(mDebugRegion, "showupdates enabled");
118c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    ALOGI_IF(mDebugDDMS, "DDMS debugging enabled");
119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
12199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::onFirstRef()
12299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
12399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.init(this);
12499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
12599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY);
12699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
12799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // Wait for the main thread to be done with its initialization
12899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mReadyToRunBarrier.wait();
12999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
13099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
13199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::~SurfaceFlinger()
133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
134a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
135a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
136a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglTerminate(display);
137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
13999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::binderDied(const wp<IBinder>& who)
14099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
14199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // the window manager died on us. prepare its eulogy.
14299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
14313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    // restore initial conditions (default device unblank, etc)
14413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    initializeDisplays();
14599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
14699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // restart the boot-animation
147a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    startBootAnim();
14899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
14999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
1507e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopiansp<ISurfaceComposerClient> SurfaceFlinger::createConnection()
151edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
15296f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<ISurfaceComposerClient> bclient;
15396f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<Client> client(new Client(this));
15496f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = client->initCheck();
15596f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR) {
15696f0819f81293076e652792794a961543e6750d7Mathias Agopian        bclient = client;
157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return bclient;
159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
161e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopiansp<IBinder> SurfaceFlinger::createDisplay()
162e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{
163e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    class DisplayToken : public BBinder {
164e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        sp<SurfaceFlinger> flinger;
165e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        virtual ~DisplayToken() {
166e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             // no more references, this display must be terminated
167e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             Mutex::Autolock _l(flinger->mStateLock);
168e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             flinger->mCurrentState.displays.removeItem(this);
169e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             flinger->setTransactionFlags(eDisplayTransactionNeeded);
170e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian         }
171e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian     public:
172e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        DisplayToken(const sp<SurfaceFlinger>& flinger)
173e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            : flinger(flinger) {
174e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
175e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    };
176e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
177e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    sp<BBinder> token = new DisplayToken(this);
178e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
179e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    Mutex::Autolock _l(mStateLock);
1803ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    DisplayDeviceState info(DisplayDevice::DISPLAY_VIRTUAL);
181e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    mCurrentState.displays.add(token, info);
182e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
183e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return token;
184e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
185e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
186e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopiansp<IBinder> SurfaceFlinger::getBuiltInDisplay(int32_t id) {
1873ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    if (uint32_t(id) >= DisplayDevice::NUM_DISPLAY_TYPES) {
188e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        ALOGE("getDefaultDisplay: id=%d is not a valid default display id", id);
189e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        return NULL;
190e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
191e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return mDefaultDisplays[id];
192e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
193e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
1949a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc()
1959a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis{
1969a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc());
1979a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    return gba;
1989a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis}
199b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
200edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::bootFinished()
201edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
202edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t now = systemTime();
203edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t duration = now - mBootTime;
204a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
2053330b203039dea366d4981db1408a460134b2d2cMathias Agopian    mBootFinished = true;
2061f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
2071f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // wait patiently for the window manager death
2081f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    const String16 name("window");
2091f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    sp<IBinder> window(defaultServiceManager()->getService(name));
2101f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    if (window != 0) {
211921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        window->linkToDeath(static_cast<IBinder::DeathRecipient*>(this));
2121f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    }
2131f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
2141f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // stop boot animation
215a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // formerly we would just kill the process, but we now ask it to exit so it
216a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // can choose where to stop the animation.
217a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("service.bootanim.exit", "1");
218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
220921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianvoid SurfaceFlinger::deleteTextureAsync(GLuint texture) {
221921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    class MessageDestroyGLTexture : public MessageBase {
222921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        GLuint texture;
223921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    public:
224921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        MessageDestroyGLTexture(GLuint texture)
225921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian            : texture(texture) {
226921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        }
227921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        virtual bool handler() {
228921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian            glDeleteTextures(1, &texture);
229921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian            return true;
230921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        }
231921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    };
232921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    postMessageAsync(new MessageDestroyGLTexture(texture));
233921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
234921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
235a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianstatus_t SurfaceFlinger::selectConfigForPixelFormat(
236a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        EGLDisplay dpy,
237a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        EGLint const* attrs,
238a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        PixelFormat format,
239a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        EGLConfig* outConfig)
240a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian{
241a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLConfig config = NULL;
242a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLint numConfigs = -1, n=0;
243a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglGetConfigs(dpy, NULL, 0, &numConfigs);
244a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLConfig* const configs = new EGLConfig[numConfigs];
245a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglChooseConfig(dpy, attrs, configs, numConfigs, &n);
246a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    for (int i=0 ; i<n ; i++) {
247a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        EGLint nativeVisualId = 0;
248a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        eglGetConfigAttrib(dpy, configs[i], EGL_NATIVE_VISUAL_ID, &nativeVisualId);
249a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        if (nativeVisualId>0 && format == nativeVisualId) {
250a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            *outConfig = configs[i];
251a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            delete [] configs;
252a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            return NO_ERROR;
253a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        }
254a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    }
255a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    delete [] configs;
256a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    return NAME_NOT_FOUND;
257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
259a49126087b4494f4ef50873f3a3f6727265f6621Mathias AgopianEGLConfig SurfaceFlinger::selectEGLConfig(EGLDisplay display, EGLint nativeVisualId) {
260a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // select our EGLConfig. It must support EGL_RECORDABLE_ANDROID if
261a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // it is to be used with WIFI displays
262a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLConfig config;
263a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLint dummy;
264a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    status_t err;
265a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLint attribs[] = {
266a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            EGL_SURFACE_TYPE,           EGL_WINDOW_BIT,
267a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            EGL_RECORDABLE_ANDROID,     EGL_TRUE,
268a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            EGL_NONE
269a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    };
270a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    err = selectConfigForPixelFormat(display, attribs, nativeVisualId, &config);
271a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    if (err) {
272a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        // maybe we failed because of EGL_RECORDABLE_ANDROID
273a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        ALOGW("couldn't find an EGLConfig with EGL_RECORDABLE_ANDROID");
274a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        attribs[2] = EGL_NONE;
275a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        err = selectConfigForPixelFormat(display, attribs, nativeVisualId, &config);
276a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    }
277a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGE_IF(err, "couldn't find an EGLConfig matching the screen format");
278a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    if (eglGetConfigAttrib(display, config, EGL_CONFIG_CAVEAT, &dummy) == EGL_TRUE) {
279a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        ALOGW_IF(dummy == EGL_SLOW_CONFIG, "EGL_SLOW_CONFIG selected!");
280a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    }
281a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    return config;
282a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
284a49126087b4494f4ef50873f3a3f6727265f6621Mathias AgopianEGLContext SurfaceFlinger::createGLContext(EGLDisplay display, EGLConfig config) {
285a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // Also create our EGLContext
286a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLint contextAttributes[] = {
287a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#ifdef EGL_IMG_context_priority
288a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#ifdef HAS_CONTEXT_PRIORITY
289a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#warning "using EGL_IMG_context_priority"
290a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_HIGH_IMG,
291a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#endif
292a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#endif
293a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            EGL_NONE, EGL_NONE
294a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    };
295a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLContext ctxt = eglCreateContext(display, config, NULL, contextAttributes);
296a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGE_IF(ctxt==EGL_NO_CONTEXT, "EGLContext creation failed");
297a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    return ctxt;
298a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
300da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopianvoid SurfaceFlinger::initializeGL(EGLDisplay display, const sp<DisplayDevice>& hw) {
301da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian    EGLBoolean result = DisplayDevice::makeCurrent(display, hw, mEGLContext);
302a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    if (!result) {
303a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        ALOGE("Couldn't create a working GLES context. check logs. exiting...");
304a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        exit(0);
305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
307a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    GLExtensions& extensions(GLExtensions::getInstance());
308a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    extensions.initWithGLStrings(
309a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            glGetString(GL_VENDOR),
310a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            glGetString(GL_RENDERER),
311a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            glGetString(GL_VERSION),
312a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            glGetString(GL_EXTENSIONS),
313a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            eglQueryString(display, EGL_VENDOR),
314a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            eglQueryString(display, EGL_VERSION),
315a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            eglQueryString(display, EGL_EXTENSIONS));
3168b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
317a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
318a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    glGetIntegerv(GL_MAX_VIEWPORT_DIMS, mMaxViewportDims);
3197303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
3218b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber    glPixelStorei(GL_PACK_ALIGNMENT, 4);
322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glEnableClientState(GL_VERTEX_ARRAY);
323edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glShadeModel(GL_FLAT);
324edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_DITHER);
325edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_CULL_FACE);
326edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
327a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    struct pack565 {
328a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        inline uint16_t operator() (int r, int g, int b) const {
329a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            return (r<<11)|(g<<5)|b;
330a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        }
331a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    } pack565;
332a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
3339575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    const uint16_t protTexData[] = { pack565(0x03, 0x03, 0x03) };
3349575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glGenTextures(1, &mProtectedTexName);
3359575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glBindTexture(GL_TEXTURE_2D, mProtectedTexName);
3369575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3379575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3389575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
3399575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
3409575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0,
3419575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis            GL_RGB, GL_UNSIGNED_SHORT_5_6_5, protTexData);
342edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
343a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // print some debugging info
344a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLint r,g,b,a;
345a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglGetConfigAttrib(display, mEGLConfig, EGL_RED_SIZE,   &r);
346a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglGetConfigAttrib(display, mEGLConfig, EGL_GREEN_SIZE, &g);
347a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglGetConfigAttrib(display, mEGLConfig, EGL_BLUE_SIZE,  &b);
348a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglGetConfigAttrib(display, mEGLConfig, EGL_ALPHA_SIZE, &a);
349a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("EGL informations:");
350a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("vendor    : %s", extensions.getEglVendor());
351a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("version   : %s", extensions.getEglVersion());
352a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("extensions: %s", extensions.getEglExtension());
353a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("Client API: %s", eglQueryString(display, EGL_CLIENT_APIS)?:"Not Supported");
354a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("EGLSurface: %d-%d-%d-%d, config=%p", r, g, b, a, mEGLConfig);
355a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("OpenGL ES informations:");
356a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("vendor    : %s", extensions.getVendor());
357a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("renderer  : %s", extensions.getRenderer());
358a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("version   : %s", extensions.getVersion());
359a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("extensions: %s", extensions.getExtension());
360a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("GL_MAX_TEXTURE_SIZE = %d", mMaxTextureSize);
361a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("GL_MAX_VIEWPORT_DIMS = %d x %d", mMaxViewportDims[0], mMaxViewportDims[1]);
362a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
363a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
364a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianstatus_t SurfaceFlinger::readyToRun()
365a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian{
366a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI(  "SurfaceFlinger's main thread ready to run. "
367a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            "Initializing graphics H/W...");
368a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
369b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden    // initialize EGL for the default display
37034a09ba1efd706323a15633da5044b352988eb5fJesse Hall    mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
37134a09ba1efd706323a15633da5044b352988eb5fJesse Hall    eglInitialize(mEGLDisplay, NULL, NULL);
372a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
373b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden    // Initialize the H/W composer object.  There may or may not be an
374b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden    // actual hardware composer underneath.
375b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden    mHwc = new HWComposer(this,
376b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden            *static_cast<HWComposer::EventHandler *>(this));
377b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden
378a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // Initialize the main display
379a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // create native window to main display
380b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden    sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc);
3811a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    if (fbs == NULL) {
382a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        ALOGE("Display subsystem failed to initialize. check logs. exiting...");
383a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        exit(0);
384a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    }
385a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
386e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    sp<SurfaceTextureClient> stc(new SurfaceTextureClient(
387e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            static_cast<sp<ISurfaceTexture> >(fbs->getBufferQueue())));
3881a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
389a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // initialize the config and context
390a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    int format;
3911a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    ANativeWindow* const anw = stc.get();
3921a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    anw->query(anw, NATIVE_WINDOW_FORMAT, &format);
39334a09ba1efd706323a15633da5044b352988eb5fJesse Hall    mEGLConfig  = selectEGLConfig(mEGLDisplay, format);
39434a09ba1efd706323a15633da5044b352988eb5fJesse Hall    mEGLContext = createGLContext(mEGLDisplay, mEGLConfig);
395a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
396a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // initialize our main display hardware
397e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
3983ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    for (size_t i=0 ; i<DisplayDevice::NUM_DISPLAY_TYPES ; i++) {
399e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        mDefaultDisplays[i] = new BBinder();
4003ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian        mCurrentState.displays.add(mDefaultDisplays[i],
4013ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian                DisplayDeviceState((DisplayDevice::DisplayType)i));
402e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
403e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    sp<DisplayDevice> hw = new DisplayDevice(this,
4043ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian            DisplayDevice::DISPLAY_PRIMARY,
4053ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian            mDefaultDisplays[DisplayDevice::DISPLAY_PRIMARY],
406e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian            anw, fbs, mEGLConfig);
4073ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    mDisplays.add(mDefaultDisplays[DisplayDevice::DISPLAY_PRIMARY], hw);
408a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
409a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    //  initialize OpenGL ES
410da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian    initializeGL(mEGLDisplay, hw);
411d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
412028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian    // start the EventThread
413028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian    mEventThread = new EventThread(this);
414028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian    mEventQueue.setEventThread(mEventThread);
415028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian
41692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    // initialize our drawing state
41792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    mDrawingState = mCurrentState;
4188630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
419a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // We're now ready to accept clients...
420d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian    mReadyToRunBarrier.open();
421d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
42213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    // set initial conditions (e.g. unblank default device)
42313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    initializeDisplays();
42413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
425a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    // start boot animation
426a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    startBootAnim();
4278b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
428edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
429edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
430edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
4313ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopianint32_t SurfaceFlinger::allocateHwcDisplayId(DisplayDevice::DisplayType type) {
4323ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    return (uint32_t(type) < DisplayDevice::NUM_DISPLAY_TYPES) ?
4333ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian            type : mHwc->allocateDisplayId();
4343ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian}
4353ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian
436a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopianvoid SurfaceFlinger::startBootAnim() {
437a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // start boot animation
438a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("service.bootanim.exit", "0");
439a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("ctl.start", "bootanim");
440a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian}
441a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian
442a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianuint32_t SurfaceFlinger::getMaxTextureSize() const {
443a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    return mMaxTextureSize;
444a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
445a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
446a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianuint32_t SurfaceFlinger::getMaxViewportDims() const {
447a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    return mMaxViewportDims[0] < mMaxViewportDims[1] ?
448a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            mMaxViewportDims[0] : mMaxViewportDims[1];
449a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
450a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
451edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
452d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
453582270d69db94286a248bd829f1ae6f910d45124Jamie Gennisbool SurfaceFlinger::authenticateSurfaceTexture(
454582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis        const sp<ISurfaceTexture>& surfaceTexture) const {
455134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    Mutex::Autolock _l(mStateLock);
456582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis    sp<IBinder> surfaceTextureBinder(surfaceTexture->asBinder());
457134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
458134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // Check the visible layer list for the ISurface
459134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
460134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    size_t count = currentLayers.size();
461134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    for (size_t i=0 ; i<count ; i++) {
462134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        const sp<LayerBase>& layer(currentLayers[i]);
463134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        sp<LayerBaseClient> lbc(layer->getLayerBaseClient());
464582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis        if (lbc != NULL) {
465582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder();
466582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            if (lbcBinder == surfaceTextureBinder) {
467582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis                return true;
468582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            }
469134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        }
470134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    }
471134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
472134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // Check the layers in the purgatory.  This check is here so that if a
473582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis    // SurfaceTexture gets destroyed before all the clients are done using it,
474582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis    // the error will not be reported as "surface XYZ is not authenticated", but
475134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // will instead fail later on when the client tries to use the surface,
476134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // which should be reported as "surface XYZ returned an -ENODEV".  The
477134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // purgatorized layers are no less authentic than the visible ones, so this
478134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // should not cause any harm.
479134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    size_t purgatorySize =  mLayerPurgatory.size();
480134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    for (size_t i=0 ; i<purgatorySize ; i++) {
481134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
482134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        sp<LayerBaseClient> lbc(layer->getLayerBaseClient());
483582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis        if (lbc != NULL) {
484582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder();
485582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            if (lbcBinder == surfaceTextureBinder) {
486582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis                return true;
487582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            }
488134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        }
489134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    }
490134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
491134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    return false;
492134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis}
493134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
4949d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brownstatus_t SurfaceFlinger::getDisplayInfo(const sp<IBinder>& display, DisplayInfo* info) {
4959d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown    // TODO: this is mostly here only for compatibility
4969d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown    //       the display size is needed but the display metrics should come from elsewhere
4979d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown    if (display != mDefaultDisplays[ISurfaceComposer::eDisplayIdMain]) {
4989d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown        // TODO: additional displays not yet supported
499c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian        return BAD_INDEX;
500c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian    }
5018b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian
5028b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    const HWComposer& hwc(getHwComposer());
503b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden    float xdpi = hwc.getDpiX(HWC_DISPLAY_PRIMARY);
504b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden    float ydpi = hwc.getDpiY(HWC_DISPLAY_PRIMARY);
5058b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian
5068b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    // TODO: Not sure if display density should handled by SF any longer
5078b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    class Density {
5088b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        static int getDensityFromProperty(char const* propName) {
5098b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            char property[PROPERTY_VALUE_MAX];
5108b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            int density = 0;
5118b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            if (property_get(propName, property, NULL) > 0) {
5128b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian                density = atoi(property);
5138b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            }
5148b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            return density;
5158b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        }
5168b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    public:
5178b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        static int getEmuDensity() {
5188b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            return getDensityFromProperty("qemu.sf.lcd_density"); }
5198b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        static int getBuildDensity()  {
5208b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            return getDensityFromProperty("ro.sf.lcd_density"); }
5218b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    };
5228b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    // The density of the device is provided by a build property
5238b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    float density = Density::getBuildDensity() / 160.0f;
5248b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    if (density == 0) {
5258b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        // the build doesn't provide a density -- this is wrong!
5268b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        // use xdpi instead
5278b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        ALOGE("ro.sf.lcd_density must be defined as a build property");
5288b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        density = xdpi / 160.0f;
5298b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    }
5308b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    if (Density::getEmuDensity()) {
5318b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        // if "qemu.sf.lcd_density" is specified, it overrides everything
5328b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        xdpi = ydpi = density = Density::getEmuDensity();
5338b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        density /= 160.0f;
5348b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    }
5358b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian
5364297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    sp<const DisplayDevice> hw(getDefaultDisplayDevice());
5374297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    info->w = hw->getWidth();
5384297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    info->h = hw->getHeight();
5398b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    info->xdpi = xdpi;
5408b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    info->ydpi = ydpi;
541b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden    info->fps = float(1e9 / hwc.getRefreshPeriod(HWC_DISPLAY_PRIMARY));
5428b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    info->density = density;
5434297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    info->orientation = hw->getOrientation();
544888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian    // TODO: this needs to go away (currently needed only by webkit)
5454297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    getPixelFormatInfo(hw->getFormat(), &info->pixelFormatInfo);
546888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian    return NO_ERROR;
547c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian}
548c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian
549d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian// ----------------------------------------------------------------------------
550d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
551d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopiansp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection() {
5528aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian    return mEventThread->createEventConnection();
553bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian}
554bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
5559d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brownvoid SurfaceFlinger::connectDisplay(const sp<ISurfaceTexture>& surface) {
5563094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
5575f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    sp<IBinder> token;
5583094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    { // scope for the lock
5593094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        Mutex::Autolock _l(mStateLock);
5605f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        token = mExtDisplayToken;
5613094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    }
5623094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
5635f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    if (token == 0) {
5645f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        token = createDisplay();
5653094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    }
5663094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
5675f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    { // scope for the lock
5685f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        Mutex::Autolock _l(mStateLock);
5695f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        if (surface == 0) {
5705f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian            // release our current display. we're guarantee to have
5715f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian            // a reference to it (token), while we hold the lock
5725f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian            mExtDisplayToken = 0;
5735f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        } else {
5745f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian            mExtDisplayToken = token;
5755f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        }
5765f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian
5775f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        DisplayDeviceState& info(mCurrentState.displays.editValueFor(token));
5785f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        info.surface = surface;
5795f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        setTransactionFlags(eDisplayTransactionNeeded);
5805f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    }
5813094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian}
5823094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
583edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
58499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
58599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::waitForEvent() {
58699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.waitMessage();
58799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
58899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
58999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalTransaction() {
59099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.invalidate();
59199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
59299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
59399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalLayerUpdate() {
59499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.invalidate();
59599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
59699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
59799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalRefresh() {
59899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.refresh();
59999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
60099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
60199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg,
60299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        nsecs_t reltime, uint32_t flags) {
60399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return mEventQueue.postMessage(msg, reltime);
60499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
60599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
60699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,
60799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        nsecs_t reltime, uint32_t flags) {
60899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    status_t res = mEventQueue.postMessage(msg, reltime);
60999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    if (res == NO_ERROR) {
61099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        msg->wait();
61199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    }
61299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return res;
61399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
614edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
6154fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianbool SurfaceFlinger::threadLoop() {
616edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    waitForEvent();
61799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return true;
61899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
619edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
6203ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopianvoid SurfaceFlinger::onVSyncReceived(int type, nsecs_t timestamp) {
62143601a2dc320a271ff8c3765ff61414a07221635Andy McFadden    if (mEventThread == NULL) {
62243601a2dc320a271ff8c3765ff61414a07221635Andy McFadden        // This is a temporary workaround for b/7145521.  A non-null pointer
62343601a2dc320a271ff8c3765ff61414a07221635Andy McFadden        // does not mean EventThread has finished initializing, so this
62443601a2dc320a271ff8c3765ff61414a07221635Andy McFadden        // is not a correct fix.
62543601a2dc320a271ff8c3765ff61414a07221635Andy McFadden        ALOGW("WARNING: EventThread not started, ignoring vsync");
62643601a2dc320a271ff8c3765ff61414a07221635Andy McFadden        return;
62743601a2dc320a271ff8c3765ff61414a07221635Andy McFadden    }
6283ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    if (uint32_t(type) < DisplayDevice::NUM_DISPLAY_TYPES) {
6293ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian        // we should only receive DisplayDevice::DisplayType from the vsync callback
6303ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian        const wp<IBinder>& token(mDefaultDisplays[type]);
6313ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian        mEventThread->onVSyncReceived(token, timestamp);
6323ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    }
6338630320433bd15aca239522e54e711ef6372ab07Mathias Agopian}
6348630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
6358630320433bd15aca239522e54e711ef6372ab07Mathias Agopianvoid SurfaceFlinger::eventControl(int event, int enabled) {
6368630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    getHwComposer().eventControl(event, enabled);
6378630320433bd15aca239522e54e711ef6372ab07Mathias Agopian}
6388630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
6394fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::onMessageReceived(int32_t what) {
6401c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
64199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    switch (what) {
6424fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    case MessageQueue::INVALIDATE:
6434fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        handleMessageTransaction();
6444fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        handleMessageInvalidate();
6454fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        signalRefresh();
6464fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        break;
6474fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    case MessageQueue::REFRESH:
6484fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        handleMessageRefresh();
6494fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        break;
6504fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
6514fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
652edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
6534fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageTransaction() {
654e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    uint32_t transactionFlags = peekTransactionFlags(eTransactionMask);
6554fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    if (transactionFlags) {
65687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        handleTransaction(transactionFlags);
6574fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
6584fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
659edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
6604fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageInvalidate() {
661cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    ATRACE_CALL();
66287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    handlePageFlip();
6634fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
6643a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian
6654fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageRefresh() {
666cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    ATRACE_CALL();
667cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    preComposition();
668cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    rebuildLayerStacks();
669cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    setUpHWComposer();
670cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    doDebugFlashRegions();
671cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    doComposition();
672cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    postComposition();
673cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
674cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
675cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doDebugFlashRegions()
676cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{
677cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    // is debugging enabled
678cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (CC_LIKELY(!mDebugRegion))
679cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        return;
680cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
681cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    const bool repaintEverything = mRepaintEverything;
682cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
683cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
684cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        if (hw->canDraw()) {
685cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            // transform the dirty region into this screen's coordinate space
686cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            const Region dirtyRegion(hw->getDirtyRegion(repaintEverything));
687cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            if (!dirtyRegion.isEmpty()) {
688cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                // redraw the whole screen
689cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                doComposeSurfaces(hw, Region(hw->bounds()));
690cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
691cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                // and draw the dirty region
692cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                glDisable(GL_TEXTURE_EXTERNAL_OES);
693cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                glDisable(GL_TEXTURE_2D);
694cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                glDisable(GL_BLEND);
695cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                glColor4f(1, 0, 1, 1);
696cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                const int32_t height = hw->getHeight();
697cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                Region::const_iterator it = dirtyRegion.begin();
698cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                Region::const_iterator const end = dirtyRegion.end();
699cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                while (it != end) {
700cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                    const Rect& r = *it++;
701cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                    GLfloat vertices[][2] = {
702cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            { r.left,  height - r.top },
703cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            { r.left,  height - r.bottom },
704cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            { r.right, height - r.bottom },
705cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            { r.right, height - r.top }
706cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                    };
707cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                    glVertexPointer(2, GL_FLOAT, 0, vertices);
708cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
709cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                }
710cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                hw->compositionComplete();
711cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                // FIXME
7123ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian                if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) {
713cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                    eglSwapBuffers(mEGLDisplay, hw->getEGLSurface());
714cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                }
715cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            }
716cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        }
717cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
718cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
719cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    postFramebuffer();
720cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
721cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (mDebugRegion > 1) {
722cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        usleep(mDebugRegion * 1000);
723cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
724cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
725cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
726cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::preComposition()
727cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{
728cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    bool needExtraInvalidate = false;
729cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
730cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    const size_t count = currentLayers.size();
731cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    for (size_t i=0 ; i<count ; i++) {
732cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        if (currentLayers[i]->onPreComposition()) {
733cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            needExtraInvalidate = true;
734cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        }
735cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
736cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (needExtraInvalidate) {
737cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        signalLayerUpdate();
738cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
739cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
740a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
741cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::postComposition()
742cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{
743cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
744cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    const size_t count = currentLayers.size();
745cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    for (size_t i=0 ; i<count ; i++) {
746cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        currentLayers[i]->onPostComposition();
747cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
748cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
749cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
750cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::rebuildLayerStacks() {
751cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    // rebuild the visible layer list per screen
75252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    if (CC_UNLIKELY(mVisibleRegionsDirty)) {
753cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        ATRACE_CALL();
75487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        mVisibleRegionsDirty = false;
75587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        invalidateHwcGeometry();
756ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian
75787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
75892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
759ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian            Region opaqueRegion;
760ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian            Region dirtyRegion;
761ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian            Vector< sp<LayerBase> > layersSortedByZ;
7624297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            const sp<DisplayDevice>& hw(mDisplays[dpy]);
7637e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian            const Transform& tr(hw->getTransform());
7647e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian            const Rect bounds(hw->getBounds());
765ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian            if (hw->canDraw()) {
766ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                SurfaceFlinger::computeVisibleRegions(currentLayers,
767ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                        hw->getLayerStack(), dirtyRegion, opaqueRegion);
7687e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian
769ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                const size_t count = currentLayers.size();
770ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                for (size_t i=0 ; i<count ; i++) {
771ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                    const sp<LayerBase>& layer(currentLayers[i]);
772ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                    const Layer::State& s(layer->drawingState());
773ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                    if (s.layerStack == hw->getLayerStack()) {
774ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                        Region visibleRegion(tr.transform(layer->visibleRegion));
775ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                        visibleRegion.andSelf(bounds);
776ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                        if (!visibleRegion.isEmpty()) {
777ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                            layersSortedByZ.add(layer);
778ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                        }
77987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian                    }
78087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian                }
7813b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian            }
7824297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->setVisibleLayersSortedByZ(layersSortedByZ);
7837e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian            hw->undefinedRegion.set(bounds);
7847e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian            hw->undefinedRegion.subtractSelf(tr.transform(opaqueRegion));
7857e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian            hw->dirtyRegion.orSelf(dirtyRegion);
7863b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        }
7873b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
788cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
7893b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
790cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::setUpHWComposer() {
79152bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    HWComposer& hwc(getHwComposer());
79252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    if (hwc.initCheck() == NO_ERROR) {
79352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        // build the h/w work list
79452bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        const bool workListsDirty = mHwWorkListDirty;
79552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        mHwWorkListDirty = false;
79692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
7974297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            sp<const DisplayDevice> hw(mDisplays[dpy]);
798e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian            const int32_t id = hw->getHwcDisplayId();
799e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian            if (id >= 0) {
800e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                const Vector< sp<LayerBase> >& currentLayers(
801cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                    hw->getVisibleLayersSortedByZ());
802e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                const size_t count = currentLayers.size();
803e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                if (hwc.createWorkList(id, count) >= 0) {
804e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                    HWComposer::LayerListIterator cur = hwc.begin(id);
805e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                    const HWComposer::LayerListIterator end = hwc.end(id);
806e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                    for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
807e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                        const sp<LayerBase>& layer(currentLayers[i]);
808e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian
809e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                        if (CC_UNLIKELY(workListsDirty)) {
810e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                            layer->setGeometry(hw, *cur);
811e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                            if (mDebugDisableHWC || mDebugRegion) {
812e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                                cur->setSkip(true);
813e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                            }
8141e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                        }
81552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian
816e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                        /*
817e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                         * update the per-frame h/w composer data for each layer
818e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                         * and build the transparent region of the FB
819e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                         */
820e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                        layer->setPerFrameData(hw, *cur);
821e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                    }
8221e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                }
82352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            }
82487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        }
82552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        status_t err = hwc.prepare();
82652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
82752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    }
828cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
82952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian
830cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doComposition() {
831cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    ATRACE_CALL();
83252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    const bool repaintEverything = android_atomic_and(0, &mRepaintEverything);
83392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
8344297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
835cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        if (hw->canDraw()) {
836cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            // transform the dirty region into this screen's coordinate space
837cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            const Region dirtyRegion(hw->getDirtyRegion(repaintEverything));
838cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            if (!dirtyRegion.isEmpty()) {
83952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian                // repaint the framebuffer (if needed)
840cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                doDisplayComposition(hw, dirtyRegion);
84152bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            }
842cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            hw->dirtyRegion.clear();
843cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            hw->flip(hw->swapRegion);
844cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            hw->swapRegion.clear();
84587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        }
84652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        // inform the h/w that we're done compositing
8474297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        hw->compositionComplete();
8484fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
84952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    postFramebuffer();
850edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
851edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
852edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer()
853edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
854841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
855b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian
856a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    const nsecs_t now = systemTime();
857a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = now;
858c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall
85952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    HWComposer& hwc(getHwComposer());
860ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall    if (hwc.initCheck() == NO_ERROR) {
8615f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        // FIXME: EGL spec says:
8625f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        //   "surface must be bound to the calling thread's current context,
8635f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        //    for the current rendering API."
864da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian        DisplayDevice::makeCurrent(mEGLDisplay, getDefaultDisplayDevice(), mEGLContext);
865e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian        hwc.commit();
86652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    }
86752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian
86892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
8694297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        sp<const DisplayDevice> hw(mDisplays[dpy]);
8704297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const Vector< sp<LayerBase> >& currentLayers(hw->getVisibleLayersSortedByZ());
87152bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        const size_t count = currentLayers.size();
872e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian        int32_t id = hw->getHwcDisplayId();
873e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian        if (id >=0 && hwc.initCheck() == NO_ERROR) {
8741e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian            HWComposer::LayerListIterator cur = hwc.begin(id);
8751e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian            const HWComposer::LayerListIterator end = hwc.end(id);
87652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            for (size_t i = 0; cur != end && i < count; ++i, ++cur) {
877d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian                currentLayers[i]->onLayerDisplayed(hw, &*cur);
87852bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            }
879cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        } else {
88052bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            for (size_t i = 0; i < count; i++) {
881d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian                currentLayers[i]->onLayerDisplayed(hw, NULL);
88252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            }
883ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall        }
884e8696a40e09b24b634214684d18526187b316a2fJamie Gennis    }
885e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
886a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mLastSwapBufferTime = systemTime() - now;
887a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = 0;
888edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
889edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
89087baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
891edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
892841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
893841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
894ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    Mutex::Autolock _l(mStateLock);
895ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    const nsecs_t now = systemTime();
896ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = now;
897ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
898ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // Here we're guaranteed that some transaction flags are set
899ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // so we can call handleTransactionLocked() unconditionally.
900ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // We call getTransactionFlags(), which will also clear the flags,
901ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // with mStateLock held to guarantee that mCurrentState won't change
902ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // until the transaction is committed.
903ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
904e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    transactionFlags = getTransactionFlags(eTransactionMask);
90587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    handleTransactionLocked(transactionFlags);
906ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
907ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mLastTransactionTime = systemTime() - now;
908ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = 0;
909ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    invalidateHwcGeometry();
910ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // here the transaction has been committed
9113d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian}
912edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
91387baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
9143d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{
9153d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    const LayerVector& currentLayers(mCurrentState.layersSortedByZ);
916edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t count = currentLayers.size();
917edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
918edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
919edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Traversal of the children
920edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * (perform the transaction for each of them if needed)
921edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
922edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
9233559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    if (transactionFlags & eTraversalNeeded) {
924edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (size_t i=0 ; i<count ; i++) {
925076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            const sp<LayerBase>& layer = currentLayers[i];
926edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
927edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (!trFlags) continue;
928edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
929edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const uint32_t flags = layer->doTransaction(0);
930edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (flags & Layer::eVisibleRegion)
931edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mVisibleRegionsDirty = true;
932edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
933edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
934edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
935edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
9363559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian     * Perform display own transactions if needed
937edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
938edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
939e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    if (transactionFlags & eDisplayTransactionNeeded) {
94092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        // here we take advantage of Vector's copy-on-write semantics to
94192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        // improve performance by skipping the transaction entirely when
94292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        // know that the lists are identical
943e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const KeyedVector<  wp<IBinder>, DisplayDeviceState>& curr(mCurrentState.displays);
944e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const KeyedVector<  wp<IBinder>, DisplayDeviceState>& draw(mDrawingState.displays);
94592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        if (!curr.isIdenticalTo(draw)) {
946edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
94792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            const size_t cc = curr.size();
94893997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                  size_t dc = draw.size();
94992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian
95092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // find the displays that were removed
95192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // (ie: in drawing state but not in current state)
95292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // also handle displays that changed
95392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // (ie: displays that are in both lists)
95492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            for (size_t i=0 ; i<dc ; i++) {
955e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                const ssize_t j = curr.indexOfKey(draw.keyAt(i));
956e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                if (j < 0) {
95792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    // in drawing state but not in current state
9583ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian                    if (!draw[i].isMainDisplay()) {
9593ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian                        mDisplays.removeItem(draw.keyAt(i));
96092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    } else {
96192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                        ALOGW("trying to remove the main display");
96292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    }
96392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                } else {
96492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    // this display is in both lists. see if something changed.
965e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                    const DisplayDeviceState& state(curr[j]);
9663ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian                    const wp<IBinder>& display(curr.keyAt(j));
967111b2d89221722d38f5b5b3ba65904ec22421839Mathias Agopian                    if (state.surface->asBinder() != draw[i].surface->asBinder()) {
968e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        // changing the surface is like destroying and
96993997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // recreating the DisplayDevice, so we just remove it
97093997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // from the drawing state, so that it get re-added
97193997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // below.
97293997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        mDisplays.removeItem(display);
97393997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        mDrawingState.displays.removeItemsAt(i);
97493997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        dc--; i--;
97593997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // at this point we must loop to the next item
97693997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        continue;
97792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    }
97893997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian
97993997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                    const sp<DisplayDevice>& disp(getDisplayDevice(display));
98093997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                    if (disp != NULL) {
98193997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        if (state.layerStack != draw[i].layerStack) {
98293997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                            disp->setLayerStack(state.layerStack);
98393997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        }
98400e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                        if ((state.orientation != draw[i].orientation)
98500e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                                || (state.viewport != draw[i].viewport)
98600e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                                || (state.frame != draw[i].frame))
98700e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                        {
98800e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                            disp->setProjection(state.orientation,
9894fb3999cea652617be5125f8a42c257467bf3c77Jeff Brown                                    state.viewport, state.frame);
99093997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        }
99192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    }
99292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                }
99392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            }
99492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian
99592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // find displays that were added
99692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // (ie: in current state but not in drawing state)
99792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            for (size_t i=0 ; i<cc ; i++) {
998e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                if (draw.indexOfKey(curr.keyAt(i)) < 0) {
999e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                    const DisplayDeviceState& state(curr[i]);
100093997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                    if (state.surface != NULL) {
100193997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        sp<SurfaceTextureClient> stc(
100293997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                                new SurfaceTextureClient(state.surface));
100393997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        const wp<IBinder>& display(curr.keyAt(i));
100493997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        sp<DisplayDevice> disp = new DisplayDevice(this,
100593997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                                state.type, display, stc, 0, mEGLConfig);
100693997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        disp->setLayerStack(state.layerStack);
100700e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                        disp->setProjection(state.orientation,
10084fb3999cea652617be5125f8a42c257467bf3c77Jeff Brown                                state.viewport, state.frame);
100993997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        mDisplays.add(display, disp);
101093997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                    }
101192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                }
101292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            }
1013edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
10143559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    }
1015edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
10163559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    /*
10173559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian     * Perform our own transaction if needed
10183559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian     */
1019edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1020cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    const LayerVector& previousLayers(mDrawingState.layersSortedByZ);
1021cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (currentLayers.size() > previousLayers.size()) {
10223559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        // layers have been added
10233559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        mVisibleRegionsDirty = true;
10243559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    }
10253559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian
10263559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    // some layers might have been removed, so
10273559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    // we need to update the regions they're exposing.
10283559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    if (mLayersRemoved) {
10293559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        mLayersRemoved = false;
10303559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        mVisibleRegionsDirty = true;
10313559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        const size_t count = previousLayers.size();
10323559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        for (size_t i=0 ; i<count ; i++) {
10333559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian            const sp<LayerBase>& layer(previousLayers[i]);
10343559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian            if (currentLayers.indexOf(layer) < 0) {
10353559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                // this layer is not visible anymore
10363559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                // TODO: we could traverse the tree from front to back and
10373559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                //       compute the actual visible region
10383559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                // TODO: we could cache the transformed region
10391501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian                const Layer::State& s(layer->drawingState());
10401501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian                Region visibleReg = s.transform.transform(
10411501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian                        Region(Rect(s.active.w, s.active.h)));
10421501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian                invalidateLayerStack(s.layerStack, visibleReg);
10430aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            }
1044edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1045edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1046edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1047edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    commitTransaction();
10484fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
10494fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
10504fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::commitTransaction()
10514fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian{
10524fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    if (!mLayersPendingRemoval.isEmpty()) {
10534fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // Notify removed layers now that they can't be drawn from
10544fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        for (size_t i = 0; i < mLayersPendingRemoval.size(); i++) {
10554fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            mLayersPendingRemoval[i]->onRemoved();
10564fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        }
10574fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        mLayersPendingRemoval.clear();
10584fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
10594fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
10604fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mDrawingState = mCurrentState;
10614fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mTransationPending = false;
10624fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mTransactionCV.broadcast();
1063edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1064edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1065edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::computeVisibleRegions(
106687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const LayerVector& currentLayers, uint32_t layerStack,
106787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        Region& outDirtyRegion, Region& outOpaqueRegion)
1068edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1069841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
1070841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
1071edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveOpaqueLayers;
1072edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveCoveredLayers;
1073edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region dirty;
1074edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
107587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    outDirtyRegion.clear();
1076edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1077edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t i = currentLayers.size();
1078edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    while (i--) {
1079076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        const sp<LayerBase>& layer = currentLayers[i];
1080edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1081edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // start with the whole surface at its current location
1082970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian        const Layer::State& s(layer->drawingState());
1083edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
108487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        // only consider the layers on the given later stack
108587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        if (s.layerStack != layerStack)
108687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            continue;
108787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
1088ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
1089ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * opaqueRegion: area of a surface that is fully opaque.
1090ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
1091edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region opaqueRegion;
1092ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1093ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
1094ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visibleRegion: area of a surface that is visible on screen
1095ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * and not fully transparent. This is essentially the layer's
1096ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * footprint minus the opaque regions above it.
1097ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * Areas covered by a translucent surface are considered visible.
1098ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
1099edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region visibleRegion;
1100ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1101ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
1102ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * coveredRegion: area of a surface that is covered by all
1103ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visible regions above it (which includes the translucent areas).
1104ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
1105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region coveredRegion;
1106ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1107ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1108ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // handle hidden surfaces by setting the visible region to empty
11093165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        if (CC_LIKELY(!(s.flags & layer_state_t::eLayerHidden) && s.alpha)) {
1110a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            const bool translucent = !layer->isOpaque();
11114fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            Rect bounds(layer->computeBounds());
1112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            visibleRegion.set(bounds);
1113ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            if (!visibleRegion.isEmpty()) {
1114ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // Remove the transparent area from the visible region
1115ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (translucent) {
11164fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    Region transparentRegionScreen;
11174fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    const Transform tr(s.transform);
11184fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    if (tr.transformed()) {
11194fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                        if (tr.preserveRects()) {
11204fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            // transform the transparent region
11214fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            transparentRegionScreen = tr.transform(s.transparentRegion);
11224fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                        } else {
11234fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            // transformation too complex, can't do the
11244fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            // transparent region optimization.
11254fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            transparentRegionScreen.clear();
11264fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                        }
11274fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    } else {
11284fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                        transparentRegionScreen = s.transparentRegion;
11294fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    }
11304fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    visibleRegion.subtractSelf(transparentRegionScreen);
1131ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
1132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1133ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // compute the opaque region
11344fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                const int32_t layerOrientation = s.transform.getOrientation();
1135ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (s.alpha==255 && !translucent &&
1136ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                        ((layerOrientation & Transform::ROT_INVALID) == false)) {
1137ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    // the opaque region is the layer's footprint
1138ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    opaqueRegion = visibleRegion;
1139ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
1140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1141edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1142edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1143ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Clip the covered region to the visible region
1144ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        coveredRegion = aboveCoveredLayers.intersect(visibleRegion);
1145ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1146ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveCoveredLayers for next (lower) layer
1147ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        aboveCoveredLayers.orSelf(visibleRegion);
1148ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1149edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // subtract the opaque region covered by the layers above us
1150edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        visibleRegion.subtractSelf(aboveOpaqueLayers);
1151edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1152edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // compute this layer's dirty region
1153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (layer->contentDirty) {
1154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // we need to invalidate the whole region
1155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dirty = visibleRegion;
1156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // as well, as the old visible region
11574fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            dirty.orSelf(layer->visibleRegion);
1158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->contentDirty = false;
1159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
1160a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian            /* compute the exposed region:
1161ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   the exposed region consists of two components:
1162ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   1) what's VISIBLE now and was COVERED before
1163ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   2) what's EXPOSED now less what was EXPOSED before
1164ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
1165ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * note that (1) is conservative, we start with the whole
1166ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * visible region but only keep what used to be covered by
1167ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * something -- which mean it may have been exposed.
1168ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
1169ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * (2) handles areas that were not covered by anything but got
1170ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * exposed because of a resize.
1171a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian             */
1172ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region newExposed = visibleRegion - coveredRegion;
11734fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region oldVisibleRegion = layer->visibleRegion;
11744fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region oldCoveredRegion = layer->coveredRegion;
1175ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldExposed = oldVisibleRegion - oldCoveredRegion;
1176ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed);
1177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirty.subtractSelf(aboveOpaqueLayers);
1179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // accumulate to the screen dirty region
118187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        outDirtyRegion.orSelf(dirty);
1182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1183ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveOpaqueLayers for next (lower) layer
1184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        aboveOpaqueLayers.orSelf(opaqueRegion);
11858b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
1186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // Store the visible region is screen space
1187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setVisibleRegion(visibleRegion);
1188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setCoveredRegion(coveredRegion);
1189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
119187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    outOpaqueRegion = aboveOpaqueLayers;
1192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
119487baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::invalidateLayerStack(uint32_t layerStack,
119587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const Region& dirty) {
119692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
11974297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
11984297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        if (hw->getLayerStack() == layerStack) {
11994297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->dirtyRegion.orSelf(dirty);
120092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        }
120192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    }
120287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian}
120387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
120487baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handlePageFlip()
1205edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
12064fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    Region dirtyRegion;
120799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
12084fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    bool visibleRegions = false;
1209cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
12104fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    const size_t count = currentLayers.size();
12114fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    for (size_t i=0 ; i<count ; i++) {
1212cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
121387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const Region dirty(layer->latchBuffer(visibleRegions));
12141501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian        const Layer::State& s(layer->drawingState());
121587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        invalidateLayerStack(s.layerStack, dirty);
12164fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
12174da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
12183b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    mVisibleRegionsDirty |= visibleRegions;
1219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1221ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopianvoid SurfaceFlinger::invalidateHwcGeometry()
1222ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian{
1223ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian    mHwWorkListDirty = true;
1224ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian}
1225ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian
122699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
1227cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doDisplayComposition(const sp<const DisplayDevice>& hw,
122887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const Region& inDirtyRegion)
1229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
123087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    Region dirtyRegion(inDirtyRegion);
123187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
1232b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // compute the invalid region
12334297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->swapRegion.orSelf(dirtyRegion);
1234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
12354297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    uint32_t flags = hw->getFlags();
12360f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian    if (flags & DisplayDevice::SWAP_RECTANGLE) {
123729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // we can redraw only what's dirty, but since SWAP_RECTANGLE only
123829d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // takes a rectangle, we must make sure to update that whole
123929d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // rectangle in that case
12404297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        dirtyRegion.set(hw->swapRegion.bounds());
1241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
12420f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian        if (flags & DisplayDevice::PARTIAL_UPDATES) {
124329d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // We need to redraw the rectangle that will be updated
1244df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian            // (pushed to the framebuffer).
124595a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian            // This is needed because PARTIAL_UPDATES only takes one
12460f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian            // rectangle instead of a region (see DisplayDevice::flip())
12474297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            dirtyRegion.set(hw->swapRegion.bounds());
1248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
124929d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // we need to redraw everything (the whole screen)
12504297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            dirtyRegion.set(hw->bounds());
12514297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->swapRegion = dirtyRegion;
1252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1255cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    doComposeSurfaces(hw, dirtyRegion);
1256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1257cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    // FIXME: we need to call eglSwapBuffers() on displays that have
1258cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    // GL composition and only on those.
1259cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    // however, currently hwc.commit() already does that for the main
12609ca48916bc9408d0f3f8ac95469ced0a6a342acaJesse Hall    // display (if there is a hwc) and never for the other ones
12619ca48916bc9408d0f3f8ac95469ced0a6a342acaJesse Hall    if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL ||
12629ca48916bc9408d0f3f8ac95469ced0a6a342acaJesse Hall            getHwComposer().initCheck() != NO_ERROR) {
1263cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        // FIXME: EGL spec says:
1264cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        //   "surface must be bound to the calling thread's current context,
1265cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        //    for the current rendering API."
1266cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        eglSwapBuffers(mEGLDisplay, hw->getEGLSurface());
1267d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    }
1268d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
12699c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    // update the swap region and clear the dirty region
12704297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->swapRegion.orSelf(dirtyRegion);
1271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1273cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& hw, const Region& dirty)
1274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
127585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    const int32_t id = hw->getHwcDisplayId();
12768630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    HWComposer& hwc(getHwComposer());
12771e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian    HWComposer::LayerListIterator cur = hwc.begin(id);
12781e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian    const HWComposer::LayerListIterator end = hwc.end(id);
1279a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
128085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    const bool hasGlesComposition = hwc.hasGlesComposition(id) || (cur==end);
128185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    if (hasGlesComposition) {
1282da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian        DisplayDevice::makeCurrent(mEGLDisplay, hw, mEGLContext);
1283a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
128452bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        // set the frame buffer
128552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        glMatrixMode(GL_MODELVIEW);
128652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        glLoadIdentity();
1287a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
1288a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        // Never touch the framebuffer if we don't have any framebuffer layers
128985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        const bool hasHwcComposition = hwc.hasHwcComposition(id);
1290e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian        if (hasHwcComposition) {
1291b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // when using overlays, we assume a fully transparent framebuffer
1292b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // NOTE: we could reduce how much we need to clear, for instance
1293b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // remove where there are opaque FB layers. however, on some
1294b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // GPUs doing a "clean slate" glClear might be more efficient.
1295b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // We'll revisit later if needed.
1296b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            glClearColor(0, 0, 0, 0);
1297b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            glClear(GL_COLOR_BUFFER_BIT);
1298b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian        } else {
12994297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            const Region region(hw->undefinedRegion.intersect(dirty));
1300b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // screen is already cleared here
130187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            if (!region.isEmpty()) {
1302b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                // can happen with SurfaceView
130355801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian                drawWormhole(hw, region);
1304b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            }
1305a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        }
130685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    }
13074b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian
130885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    /*
130985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian     * and then, render the layers targeted at the framebuffer
131085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian     */
13114b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian
131285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    const Vector< sp<LayerBase> >& layers(hw->getVisibleLayersSortedByZ());
131385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    const size_t count = layers.size();
131485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    const Transform& tr = hw->getTransform();
131585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    if (cur != end) {
131685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        // we're using h/w composer
131785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        for (size_t i=0 ; i<count && cur!=end ; ++i, ++cur) {
1318a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian            const sp<LayerBase>& layer(layers[i]);
13194fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region clip(dirty.intersect(tr.transform(layer->visibleRegion)));
132085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            if (!clip.isEmpty()) {
132185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                switch (cur->getCompositionType()) {
132285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                    case HWC_OVERLAY: {
132385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                        if ((cur->getHints() & HWC_HINT_CLEAR_FB)
132485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                                && i
132585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                                && layer->isOpaque()
132685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                                && hasGlesComposition) {
1327cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            // never clear the very first layer since we're
1328cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            // guaranteed the FB is already cleared
1329cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            layer->clearWithOpenGL(hw, clip);
1330cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                        }
133185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                        break;
133285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                    }
133385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                    case HWC_FRAMEBUFFER: {
1334cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                        layer->draw(hw, clip);
133585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                        break;
1336a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                    }
1337cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                }
1338a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall            }
133985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            layer->setAcquireFence(hw, *cur);
134085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        }
134185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    } else {
134285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        // we're not using h/w composer
134385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        for (size_t i=0 ; i<count ; ++i) {
134485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            const sp<LayerBase>& layer(layers[i]);
134585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            const Region clip(dirty.intersect(
134685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                    tr.transform(layer->visibleRegion)));
134785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            if (!clip.isEmpty()) {
134885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                layer->draw(hw, clip);
134985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            }
13504b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian        }
13514b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian    }
1352edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1353edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
135455801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopianvoid SurfaceFlinger::drawWormhole(const sp<const DisplayDevice>& hw,
135555801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian        const Region& region) const
1356edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1357f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    glDisable(GL_TEXTURE_EXTERNAL_OES);
1358b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian    glDisable(GL_TEXTURE_2D);
1359f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    glDisable(GL_BLEND);
1360b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian    glColor4f(0,0,0,0);
1361f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian
136255801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian    const int32_t height = hw->getHeight();
1363f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    Region::const_iterator it = region.begin();
1364f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    Region::const_iterator const end = region.end();
1365f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    while (it != end) {
1366f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        const Rect& r = *it++;
136755801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian        GLfloat vertices[][2] = {
136855801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian                { r.left,  height - r.top },
136955801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian                { r.left,  height - r.bottom },
137055801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian                { r.right, height - r.bottom },
137155801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian                { r.right, height - r.top }
137255801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian        };
137355801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian        glVertexPointer(2, GL_FLOAT, 0, vertices);
1374f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1375f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    }
1376edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1377edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
137896f0819f81293076e652792794a961543e6750d7Mathias Agopianssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
137996f0819f81293076e652792794a961543e6750d7Mathias Agopian        const sp<LayerBaseClient>& lbc)
13801b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
138196f0819f81293076e652792794a961543e6750d7Mathias Agopian    // attach this layer to the client
13824f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    size_t name = client->attachLayer(lbc);
13834f113740180b6512b43723c4728f262882dc9b45Mathias Agopian
138496f0819f81293076e652792794a961543e6750d7Mathias Agopian    // add this layer to the current state list
1385921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    Mutex::Autolock _l(mStateLock);
1386921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    mCurrentState.layersSortedByZ.add(lbc);
138796f0819f81293076e652792794a961543e6750d7Mathias Agopian
13884f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    return ssize_t(name);
138996f0819f81293076e652792794a961543e6750d7Mathias Agopian}
139096f0819f81293076e652792794a961543e6750d7Mathias Agopian
139196f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer)
139296f0819f81293076e652792794a961543e6750d7Mathias Agopian{
139396f0819f81293076e652792794a961543e6750d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
139496f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = purgatorizeLayer_l(layer);
139596f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR)
13963559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        setTransactionFlags(eTransactionNeeded);
139796f0819f81293076e652792794a961543e6750d7Mathias Agopian    return err;
1398edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1399edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1400076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase)
1401edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1402edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase);
1403edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (index >= 0) {
1404076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved = true;
1405edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
1406edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
14073d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    return status_t(index);
1408edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1409edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
14109a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase)
14119a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
141276cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    // First add the layer to the purgatory list, which makes sure it won't
141376cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    // go away, then remove it from the main list (through a transaction).
14149a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    ssize_t err = removeLayer_l(layerBase);
141576cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    if (err >= 0) {
141676cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian        mLayerPurgatory.add(layerBase);
141776cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    }
14188c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian
14192f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall    mLayersPendingRemoval.push(layerBase);
14200b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian
14213d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // it's possible that we don't find a layer, because it might
14223d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // have been destroyed already -- this is not technically an error
142396f0819f81293076e652792794a961543e6750d7Mathias Agopian    // from the user because there is a race between Client::destroySurface(),
142496f0819f81293076e652792794a961543e6750d7Mathias Agopian    // ~Client() and ~ISurface().
14259a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err;
14269a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
14279a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
1428dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopianuint32_t SurfaceFlinger::peekTransactionFlags(uint32_t flags)
1429dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian{
1430dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian    return android_atomic_release_load(&mTransactionFlags);
1431dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian}
1432dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian
1433edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags)
1434edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1435edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return android_atomic_and(~flags, &mTransactionFlags) & flags;
1436edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1437edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1438bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags)
1439edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1440edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t old = android_atomic_or(flags, &mTransactionFlags);
1441edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((old & flags)==0) { // wake the server up
144299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        signalTransaction();
1443edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1444edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return old;
1445edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1446edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
14478b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopianvoid SurfaceFlinger::setTransactionState(
14488b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        const Vector<ComposerState>& state,
14498b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        const Vector<DisplayState>& displays,
14508b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        uint32_t flags)
14518b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian{
1452698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
145328378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    uint32_t transactionFlags = 0;
1454e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
1455e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    size_t count = displays.size();
1456e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
1457e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const DisplayState& s(displays[i]);
1458e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        transactionFlags |= setDisplayStateLocked(s);
1459b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis    }
1460b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis
1461e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    count = state.size();
1462698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
1463698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const ComposerState& s(state[i]);
1464698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        sp<Client> client( static_cast<Client *>(s.client.get()) );
146528378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        transactionFlags |= setClientStateLocked(client, s.state);
1466698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    }
1467386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian
146828378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    if (transactionFlags) {
1469386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // this triggers the transaction
147028378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        setTransactionFlags(transactionFlags);
1471698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian
1472386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // if this is a synchronous transaction, wait for it to take effect
1473386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // before returning.
1474386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        if (flags & eSynchronous) {
1475386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            mTransationPending = true;
1476386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        }
1477386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        while (mTransationPending) {
1478386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
1479386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            if (CC_UNLIKELY(err != NO_ERROR)) {
1480386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                // just in case something goes wrong in SF, return to the
1481386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                // called after a few seconds.
148232397c1cd3327905173b36baa6fd1c579bc328ffSteve Block                ALOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!");
1483386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                mTransationPending = false;
1484386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                break;
1485386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            }
1486cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        }
1487edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1488edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1489edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1490e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setDisplayStateLocked(const DisplayState& s)
1491e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{
1492e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    uint32_t flags = 0;
1493e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    DisplayDeviceState& disp(mCurrentState.displays.editValueFor(s.token));
14943ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    if (disp.isValid()) {
1495e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const uint32_t what = s.what;
1496e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & DisplayState::eSurfaceChanged) {
1497e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.surface->asBinder() != s.surface->asBinder()) {
1498e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.surface = s.surface;
1499e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
1500e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1501e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1502e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & DisplayState::eLayerStackChanged) {
1503e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.layerStack != s.layerStack) {
1504e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.layerStack = s.layerStack;
1505e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
1506e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1507e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
150800e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian        if (what & DisplayState::eDisplayProjectionChanged) {
1509e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.orientation != s.orientation) {
1510e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.orientation = s.orientation;
1511e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
1512e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1513e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.frame != s.frame) {
1514e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.frame = s.frame;
1515e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
1516e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1517e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.viewport != s.viewport) {
1518e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.viewport = s.viewport;
1519e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
1520e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1521e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1522e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
1523e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return flags;
1524e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
1525e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
1526e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setClientStateLocked(
1527e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const sp<Client>& client,
1528e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const layer_state_t& s)
1529e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{
1530e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    uint32_t flags = 0;
1531e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    sp<LayerBaseClient> layer(client->getLayerUser(s.surface));
1532e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    if (layer != 0) {
1533e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const uint32_t what = s.what;
1534e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::ePositionChanged) {
1535e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setPosition(s.x, s.y))
1536e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1537e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1538e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eLayerChanged) {
1539e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            // NOTE: index needs to be calculated before we update the state
1540e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
1541e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setLayer(s.z)) {
1542e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.removeAt(idx);
1543e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.add(layer);
1544e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // we need traversal (state changed)
1545e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // AND transaction (list changed)
1546e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTransactionNeeded|eTraversalNeeded;
1547e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1548e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1549e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eSizeChanged) {
1550e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setSize(s.w, s.h)) {
1551e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1552e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1553e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1554e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eAlphaChanged) {
1555e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f)))
1556e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1557e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1558e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eMatrixChanged) {
1559e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setMatrix(s.matrix))
1560e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1561e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1562e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eTransparentRegionChanged) {
1563e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setTransparentRegionHint(s.transparentRegion))
1564e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1565e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1566e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eVisibilityChanged) {
1567e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setFlags(s.flags, s.mask))
1568e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1569e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1570e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eCropChanged) {
1571e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setCrop(s.crop))
1572e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1573e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1574e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eLayerStackChanged) {
1575e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            // NOTE: index needs to be calculated before we update the state
1576e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
1577e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setLayerStack(s.layerStack)) {
1578e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.removeAt(idx);
1579e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.add(layer);
1580e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // we need traversal (state changed)
1581e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // AND transaction (list changed)
1582e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTransactionNeeded|eTraversalNeeded;
1583e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1584e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1585e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
1586e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return flags;
1587e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
1588e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
1589921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopiansp<ISurface> SurfaceFlinger::createLayer(
15900ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        ISurfaceComposerClient::surface_data_t* params,
15910ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const String8& name,
15920ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const sp<Client>& client,
15933ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian       uint32_t w, uint32_t h, PixelFormat format,
1594edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t flags)
1595edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1596076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBaseClient> layer;
1597a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    sp<ISurface> surfaceHandle;
15986e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian
15996e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    if (int32_t(w|h) < 0) {
1600921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        ALOGE("createLayer() failed, w or h is negative (w=%d, h=%d)",
16016e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian                int(w), int(h));
16026e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian        return surfaceHandle;
16036e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    }
16048b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
1605921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    //ALOGD("createLayer for (%d x %d), name=%s", w, h, name.string());
16063165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian    switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {
16073165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        case ISurfaceComposerClient::eFXSurfaceNormal:
16083ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian            layer = createNormalLayer(client, w, h, flags, format);
1609edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
16103165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        case ISurfaceComposerClient::eFXSurfaceBlur:
16113165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        case ISurfaceComposerClient::eFXSurfaceDim:
16123ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian            layer = createDimLayer(client, w, h, flags);
1613edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
16143165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        case ISurfaceComposerClient::eFXSurfaceScreenshot:
16153ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian            layer = createScreenshotLayer(client, w, h, flags);
1616118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian            break;
1617edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1618edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1619076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (layer != 0) {
162096f0819f81293076e652792794a961543e6750d7Mathias Agopian        layer->initStates(w, h, flags);
1621285dbde2e0cd0057be070ded3be8f5f453147edcMathias Agopian        layer->setName(name);
162296f0819f81293076e652792794a961543e6750d7Mathias Agopian        ssize_t token = addClientLayer(client, layer);
1623edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        surfaceHandle = layer->getSurface();
16248b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber        if (surfaceHandle != 0) {
162596f0819f81293076e652792794a961543e6750d7Mathias Agopian            params->token = token;
1626a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            params->identity = layer->getIdentity();
16271c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        }
162896f0819f81293076e652792794a961543e6750d7Mathias Agopian        setTransactionFlags(eTransactionNeeded);
1629edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1630edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1631edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return surfaceHandle;
1632edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1633edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1634921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopiansp<Layer> SurfaceFlinger::createNormalLayer(
16353ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian        const sp<Client>& client,
163696f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags,
16371c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        PixelFormat& format)
1638edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1639edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize the surfaces
164092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    switch (format) {
1641edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSPARENT:
1642edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSLUCENT:
1643edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        format = PIXEL_FORMAT_RGBA_8888;
1644edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1645edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_OPAQUE:
1646a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888
1647a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian        format = PIXEL_FORMAT_RGB_565;
1648a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#else
16498f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian        format = PIXEL_FORMAT_RGBX_8888;
1650a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif
1651edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1652edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1653edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1654a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888
1655a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian    if (format == PIXEL_FORMAT_RGBX_8888)
1656a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian        format = PIXEL_FORMAT_RGBA_8888;
1657a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif
1658a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian
16593ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    sp<Layer> layer = new Layer(this, client);
1660f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian    status_t err = layer->setBuffers(w, h, format, flags);
166199ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten    if (CC_LIKELY(err != NO_ERROR)) {
1662921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        ALOGE("createNormalLayer() failed (%s)", strerror(-err));
1663076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        layer.clear();
1664edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1665edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1666edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1667edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1668921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopiansp<LayerDim> SurfaceFlinger::createDimLayer(
16693ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian        const sp<Client>& client,
167096f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags)
1671edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
16723ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    sp<LayerDim> layer = new LayerDim(this, client);
1673118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    return layer;
1674118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
1675118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
1676921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopiansp<LayerScreenshot> SurfaceFlinger::createScreenshotLayer(
16773ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian        const sp<Client>& client,
1678118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags)
1679118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{
16803ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    sp<LayerScreenshot> layer = new LayerScreenshot(this, client);
1681edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1682edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1683edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1684921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianstatus_t SurfaceFlinger::onLayerRemoved(const sp<Client>& client, SurfaceID sid)
16859a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
16869a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    /*
16879a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     * called by the window manager, when a surface should be marked for
16889a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     * destruction.
16898b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber     *
16900aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * The surface is removed from the current and drawing lists, but placed
16910aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * in the purgatory queue, so it's not destroyed right-away (we need
16920aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * to wait for all client's references to go away first).
16939a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     */
16949a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
169548d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    status_t err = NAME_NOT_FOUND;
16960aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian    Mutex::Autolock _l(mStateLock);
169796f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<LayerBaseClient> layer = client->getLayerUser(sid);
1698b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam
169948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    if (layer != 0) {
170048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        err = purgatorizeLayer_l(layer);
170148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        if (err == NO_ERROR) {
170213233e067b8f71adc3a0ade5f442265e1f27084bMathias Agopian            setTransactionFlags(eTransactionNeeded);
170348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        }
17049a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    }
17059a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return err;
17069a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
17079a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
1708921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianstatus_t SurfaceFlinger::onLayerDestroyed(const wp<LayerBaseClient>& layer)
1709edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1710759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian    // called by ~ISurface() when all references are gone
1711ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    status_t err = NO_ERROR;
1712ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    sp<LayerBaseClient> l(layer.promote());
1713ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    if (l != NULL) {
1714ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        Mutex::Autolock _l(mStateLock);
1715ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        err = removeLayer_l(l);
1716ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        if (err == NAME_NOT_FOUND) {
1717ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // The surface wasn't in the current list, which means it was
1718ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // removed already, which means it is in the purgatory,
1719ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // and need to be removed from there.
1720ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            ssize_t idx = mLayerPurgatory.remove(l);
1721e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block            ALOGE_IF(idx < 0,
1722ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian                    "layer=%p is not in the purgatory list", l.get());
1723f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        }
1724e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE_IF(err<0 && err != NAME_NOT_FOUND,
1725ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian                "error removing layer=%p (%s)", l.get(), strerror(-err));
1726ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    }
1727ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    return err;
1728edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1729edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1730b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// ---------------------------------------------------------------------------
1731b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
173213a082e160c2d1d8006b93a555a57035213d568bAndy McFaddenvoid SurfaceFlinger::onInitializeDisplays() {
173313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    // reset screen orientation
173413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    Vector<ComposerState> state;
173513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    Vector<DisplayState> displays;
173613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    DisplayState d;
173700e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian    d.what = DisplayState::eDisplayProjectionChanged;
17383ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    d.token = mDefaultDisplays[DisplayDevice::DISPLAY_PRIMARY];
173913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    d.orientation = DisplayState::eOrientationDefault;
17404c05dd175ee3bd5119eecf368742b6510a8cfa6cJeff Brown    d.frame.makeInvalid();
17414c05dd175ee3bd5119eecf368742b6510a8cfa6cJeff Brown    d.viewport.makeInvalid();
174213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    displays.add(d);
174313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    setTransactionState(state, displays, 0);
174413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
174513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    // XXX: this should init default device to "unblank" and all other devices to "blank"
174613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    onScreenAcquired();
174713a082e160c2d1d8006b93a555a57035213d568bAndy McFadden}
174813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
174913a082e160c2d1d8006b93a555a57035213d568bAndy McFaddenvoid SurfaceFlinger::initializeDisplays() {
175013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    class MessageScreenInitialized : public MessageBase {
175113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden        SurfaceFlinger* flinger;
175213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    public:
175313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden        MessageScreenInitialized(SurfaceFlinger* flinger) : flinger(flinger) { }
175413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden        virtual bool handler() {
175513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden            flinger->onInitializeDisplays();
175613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden            return true;
175713a082e160c2d1d8006b93a555a57035213d568bAndy McFadden        }
175813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    };
175913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    sp<MessageBase> msg = new MessageScreenInitialized(this);
176013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    postMessageAsync(msg);  // we may be called from main thread, use async message
176113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden}
176213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
176313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
1764b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopianvoid SurfaceFlinger::onScreenAcquired() {
17658e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross    ALOGD("Screen about to return, flinger = %p", this);
17664297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    sp<const DisplayDevice> hw(getDefaultDisplayDevice()); // XXX: this should be per DisplayDevice
17678630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    getHwComposer().acquire();
17684297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->acquireScreen();
176922ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian    mEventThread->onScreenAcquired();
177020128300e0cb7f459a60cfbcddb48190ce6545edMathias Agopian    mVisibleRegionsDirty = true;
177120128300e0cb7f459a60cfbcddb48190ce6545edMathias Agopian    repaintEverything();
1772edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1773edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1774b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopianvoid SurfaceFlinger::onScreenReleased() {
17758e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross    ALOGD("About to give-up screen, flinger = %p", this);
17764297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    sp<const DisplayDevice> hw(getDefaultDisplayDevice()); // XXX: this should be per DisplayDevice
17774297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    if (hw->isScreenAcquired()) {
177822ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian        mEventThread->onScreenReleased();
17794297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        hw->releaseScreen();
17808630320433bd15aca239522e54e711ef6372ab07Mathias Agopian        getHwComposer().release();
1781ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian        mVisibleRegionsDirty = true;
1782b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        // from this point on, SF will stop drawing
1783b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    }
1784b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian}
1785b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
17868e533069e5721e55cb9768e140e16546c3a4a8b6Colin Crossvoid SurfaceFlinger::unblank() {
1787b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    class MessageScreenAcquired : public MessageBase {
1788b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        SurfaceFlinger* flinger;
1789b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    public:
1790b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        MessageScreenAcquired(SurfaceFlinger* flinger) : flinger(flinger) { }
1791b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        virtual bool handler() {
1792b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            flinger->onScreenAcquired();
1793b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            return true;
1794b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        }
1795b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    };
1796b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    sp<MessageBase> msg = new MessageScreenAcquired(this);
1797b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    postMessageSync(msg);
1798edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1799edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
18008e533069e5721e55cb9768e140e16546c3a4a8b6Colin Crossvoid SurfaceFlinger::blank() {
1801b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    class MessageScreenReleased : public MessageBase {
1802b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        SurfaceFlinger* flinger;
1803b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    public:
1804b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        MessageScreenReleased(SurfaceFlinger* flinger) : flinger(flinger) { }
1805b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        virtual bool handler() {
1806b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            flinger->onScreenReleased();
1807b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            return true;
1808b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        }
1809b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    };
1810b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    sp<MessageBase> msg = new MessageScreenReleased(this);
1811b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    postMessageSync(msg);
1812b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian}
1813b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
1814b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// ---------------------------------------------------------------------------
1815b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
1816edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
1817edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
18181d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling    const size_t SIZE = 4096;
1819edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char buffer[SIZE];
1820edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    String8 result;
182199b49840d309727678b77403d6cc9f920111623fMathias Agopian
182299b49840d309727678b77403d6cc9f920111623fMathias Agopian    if (!PermissionCache::checkCallingPermission(sDump)) {
1823edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        snprintf(buffer, SIZE, "Permission Denial: "
1824edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                "can't dump SurfaceFlinger from pid=%d, uid=%d\n",
1825edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                IPCThreadState::self()->getCallingPid(),
1826edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                IPCThreadState::self()->getCallingUid());
1827edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        result.append(buffer);
1828edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
18299795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // Try to get the main lock, but don't insist if we can't
18309795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // (this would indicate SF is stuck, but we want to be able to
18319795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // print something in dumpsys).
18329795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        int retry = 3;
18339795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        while (mStateLock.tryLock()<0 && --retry>=0) {
18349795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            usleep(1000000);
18359795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
18369795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const bool locked(retry >= 0);
18379795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (!locked) {
18388b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber            snprintf(buffer, SIZE,
18399795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "SurfaceFlinger appears to be unresponsive, "
18409795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "dumping anyways (no locks held)\n");
18419795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            result.append(buffer);
18429795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
18439795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
184482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        bool dumpAll = true;
184582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        size_t index = 0;
184625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        size_t numArgs = args.size();
184725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        if (numArgs) {
184825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
184925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--list"))) {
185025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                index++;
185125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                listLayersLocked(args, index, result, buffer, SIZE);
185235aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
185325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            }
185425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
185525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
185625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--latency"))) {
185782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                index++;
185882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                dumpStatsLocked(args, index, result, buffer, SIZE);
185935aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
186082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            }
186125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
186225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
186325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--latency-clear"))) {
186425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                index++;
186525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                clearStatsLocked(args, index, result, buffer, SIZE);
186635aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
186725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            }
1868edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
18691b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
187082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (dumpAll) {
187182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            dumpAllLocked(result, buffer, SIZE);
187282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
187348b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
187482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (locked) {
187582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mStateLock.unlock();
187648b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        }
187782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
187882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    write(fd, result.string(), result.size());
187982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    return NO_ERROR;
188082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
188148b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
188225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::listLayersLocked(const Vector<String16>& args, size_t& index,
188325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        String8& result, char* buffer, size_t SIZE) const
188425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
188525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
188625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const size_t count = currentLayers.size();
188725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
188825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
188925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        snprintf(buffer, SIZE, "%s\n", layer->getName().string());
189025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        result.append(buffer);
189125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
189225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
189325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
189482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index,
189582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        String8& result, char* buffer, size_t SIZE) const
189682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
189782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    String8 name;
189882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    if (index < args.size()) {
189982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        name = String8(args[index]);
190082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        index++;
190182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
190248b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
190382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
190482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const size_t count = currentLayers.size();
190582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    for (size_t i=0 ; i<count ; i++) {
190682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
190782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (name.isEmpty()) {
190882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            snprintf(buffer, SIZE, "%s\n", layer->getName().string());
190982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            result.append(buffer);
191082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
191182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (name.isEmpty() || (name == layer->getName())) {
191282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            layer->dumpStats(result, buffer, SIZE);
191382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
191482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
191582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
1916ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian
191725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& index,
191825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        String8& result, char* buffer, size_t SIZE) const
191925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
192025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    String8 name;
192125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    if (index < args.size()) {
192225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        name = String8(args[index]);
192325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        index++;
192425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
192525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
192625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
192725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const size_t count = currentLayers.size();
192825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
192925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
193025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        if (name.isEmpty() || (name == layer->getName())) {
193125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            layer->clearStats();
193225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        }
193325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
193425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
193525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
193682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpAllLocked(
193782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        String8& result, char* buffer, size_t SIZE) const
193882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
193982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    // figure out if we're stuck somewhere
194082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t now = systemTime();
194182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t inSwapBuffers(mDebugInSwapBuffers);
194282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t inTransaction(mDebugInTransaction);
194382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0;
194482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0;
1945bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
194682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
194782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump the visible layer list
194882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
194982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
195082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const size_t count = currentLayers.size();
195182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "Visible layers (count = %d)\n", count);
195282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
195382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    for (size_t i=0 ; i<count ; i++) {
195482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
195582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        layer->dump(result, buffer, SIZE);
195682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
1957bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
195882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
195982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump the layers in the purgatory
196082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
1961ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian
196282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const size_t purgatorySize = mLayerPurgatory.size();
196382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "Purgatory state (%d entries)\n", purgatorySize);
196482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
196582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    for (size_t i=0 ; i<purgatorySize ; i++) {
196682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
196782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        layer->shortDump(result, buffer, SIZE);
196882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
19691b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
197082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
19715f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian     * Dump Display state
19725f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian     */
19735f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian
19745f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
19755f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        const sp<const DisplayDevice>& hw(mDisplays[dpy]);
19765f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        snprintf(buffer, SIZE,
19775f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian                "+ DisplayDevice[%u]\n"
19784fb3999cea652617be5125f8a42c257467bf3c77Jeff Brown                "   type=%x, layerStack=%u, (%4dx%4d), orient=%2d (type=%08x), "
1979da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian                "flips=%u, secure=%d, numLayers=%u, v:[%d,%d,%d,%d], f:[%d,%d,%d,%d]\n",
19805f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian                dpy,
19813ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian                hw->getDisplayType(), hw->getLayerStack(),
19825f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian                hw->getWidth(), hw->getHeight(),
19835f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian                hw->getOrientation(), hw->getTransform().getType(),
19845f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian                hw->getPageFlipCount(),
19855f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian                hw->getSecureLayerVisible(),
1986da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian                hw->getVisibleLayersSortedByZ().size(),
1987da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian                hw->getViewport().left, hw->getViewport().top, hw->getViewport().right, hw->getViewport().bottom,
1988da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian                hw->getFrame().left, hw->getFrame().top, hw->getFrame().right, hw->getFrame().bottom);
1989da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian
19905f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        result.append(buffer);
19915f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    }
19925f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian
19935f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    /*
199482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump SurfaceFlinger global state
199582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
19961b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
199782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "SurfaceFlinger global state:\n");
199882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
19991b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
2000888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian    HWComposer& hwc(getHwComposer());
20014297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    sp<const DisplayDevice> hw(getDefaultDisplayDevice());
200282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const GLExtensions& extensions(GLExtensions::getInstance());
200382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "GLES: %s, %s, %s\n",
200482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            extensions.getVendor(),
200582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            extensions.getRenderer(),
200682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            extensions.getVersion());
200782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
2008d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
200982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "EGL : %s\n",
2010d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian            eglQueryString(mEGLDisplay, EGL_VERSION_HW_ANDROID));
201182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
201273d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian
201382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "EXTS: %s\n", extensions.getExtension());
201482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
20159795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
20164297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->undefinedRegion.dump(result, "undefinedRegion");
201782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE,
201882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  orientation=%d, canDraw=%d\n",
20194297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->getOrientation(), hw->canDraw());
202082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
202182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE,
202282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  last eglSwapBuffers() time: %f us\n"
202382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  last transaction time     : %f us\n"
2024c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian            "  transaction-flags         : %08x\n"
202582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  refresh-rate              : %f fps\n"
202682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  x-dpi                     : %f\n"
20278b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            "  y-dpi                     : %f\n",
202882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mLastSwapBufferTime/1000.0,
202982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mLastTransactionTime/1000.0,
2030c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian            mTransactionFlags,
2031b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden            1e9 / hwc.getRefreshPeriod(HWC_DISPLAY_PRIMARY),
2032b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden            hwc.getDpiX(HWC_DISPLAY_PRIMARY),
2033b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden            hwc.getDpiY(HWC_DISPLAY_PRIMARY));
203482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
203582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
203682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "  eglSwapBuffers time: %f us\n",
203782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            inSwapBuffersDuration/1000.0);
203882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
203982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
204082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "  transaction time: %f us\n",
204182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            inTransactionDuration/1000.0);
204282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
204382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
204482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
204582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * VSYNC state
204682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
204782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    mEventThread->dump(result, buffer, SIZE);
204882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
204982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
205082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump HWComposer state
205182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
205282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "h/w composer state:\n");
205382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
205482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "  h/w composer %s and %s\n",
205582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            hwc.initCheck()==NO_ERROR ? "present" : "not present",
205682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                    (mDebugDisableHWC || mDebugRegion) ? "disabled" : "enabled");
205782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
20584297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hwc.dump(result, buffer, SIZE, hw->getVisibleLayersSortedByZ());
205982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
206082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
206182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump gralloc state
206282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
206382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
206482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    alloc.dump(result);
20654297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->dump(result);
2066edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2067edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
206863f165fd6b86d04be94d4023e845e98560504a96Keun young Parkbool SurfaceFlinger::startDdmConnection()
206963f165fd6b86d04be94d4023e845e98560504a96Keun young Park{
207063f165fd6b86d04be94d4023e845e98560504a96Keun young Park    void* libddmconnection_dso =
207163f165fd6b86d04be94d4023e845e98560504a96Keun young Park            dlopen("libsurfaceflinger_ddmconnection.so", RTLD_NOW);
207263f165fd6b86d04be94d4023e845e98560504a96Keun young Park    if (!libddmconnection_dso) {
207363f165fd6b86d04be94d4023e845e98560504a96Keun young Park        return false;
207463f165fd6b86d04be94d4023e845e98560504a96Keun young Park    }
207563f165fd6b86d04be94d4023e845e98560504a96Keun young Park    void (*DdmConnection_start)(const char* name);
207663f165fd6b86d04be94d4023e845e98560504a96Keun young Park    DdmConnection_start =
207763f165fd6b86d04be94d4023e845e98560504a96Keun young Park            (typeof DdmConnection_start)dlsym(libddmconnection_dso, "DdmConnection_start");
207863f165fd6b86d04be94d4023e845e98560504a96Keun young Park    if (!DdmConnection_start) {
207963f165fd6b86d04be94d4023e845e98560504a96Keun young Park        dlclose(libddmconnection_dso);
208063f165fd6b86d04be94d4023e845e98560504a96Keun young Park        return false;
208163f165fd6b86d04be94d4023e845e98560504a96Keun young Park    }
208263f165fd6b86d04be94d4023e845e98560504a96Keun young Park    (*DdmConnection_start)(getServiceName());
208363f165fd6b86d04be94d4023e845e98560504a96Keun young Park    return true;
208463f165fd6b86d04be94d4023e845e98560504a96Keun young Park}
208563f165fd6b86d04be94d4023e845e98560504a96Keun young Park
2086edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::onTransact(
2087edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
2088edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2089edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (code) {
2090edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case CREATE_CONNECTION:
2091698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        case SET_TRANSACTION_STATE:
2092edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case BOOT_FINISHED:
20938e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross        case BLANK:
20948e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross        case UNBLANK:
2095edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        {
2096edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // codes that require permission check
2097edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            IPCThreadState* ipc = IPCThreadState::self();
2098edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int pid = ipc->getCallingPid();
2099a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian            const int uid = ipc->getCallingUid();
210099b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
210199b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) {
2102e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block                ALOGE("Permission Denial: "
2103375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                        "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
2104375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                return PERMISSION_DENIED;
2105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
21061b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
21071b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
21081b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        case CAPTURE_SCREEN:
21091b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
21101b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            // codes that require permission check
21111b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
21121b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int pid = ipc->getCallingPid();
21131b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int uid = ipc->getCallingUid();
211499b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
211599b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) {
2116e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block                ALOGE("Permission Denial: "
21171b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                        "can't read framebuffer pid=%d, uid=%d", pid, uid);
21181b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                return PERMISSION_DENIED;
21191b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            }
21201b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
2121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
2122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
21231b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
2124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
2125edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
2126b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        CHECK_INTERFACE(ISurfaceComposer, data, reply);
212799ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten        if (CC_UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) {
2128375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
2129375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int pid = ipc->getCallingPid();
2130375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int uid = ipc->getCallingUid();
2131e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block            ALOGE("Permission Denial: "
2132375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                    "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
2133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return PERMISSION_DENIED;
2134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
2135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int n;
2136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        switch (code) {
213701b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian            case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE
213835b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian            case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE
2139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
2140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1002:  // SHOW_UPDATES
2141edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                n = data.readInt32();
2142edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDebugRegion = n ? n : (mDebugRegion ? 0 : 1);
214353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
214453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
2145edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
2146edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1004:{ // repaint everything
214753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
2148cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
2149cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            }
2150cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            case 1005:{ // force transaction
2151e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                setTransactionFlags(
2152e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        eTransactionNeeded|
2153e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        eDisplayTransactionNeeded|
2154e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        eTraversalNeeded);
2155cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
2156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
21574d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            case 1006:{ // send empty update
21584d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian                signalRefresh();
21594d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian                return NO_ERROR;
21604d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            }
216153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian            case 1008:  // toggle use of hw composer
216253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                n = data.readInt32();
216353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                mDebugDisableHWC = n ? 1 : 0;
216453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
216553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
216653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                return NO_ERROR;
2167a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian            case 1009:  // toggle use of transform hint
2168a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                n = data.readInt32();
2169a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                mDebugDisableTransformHint = n ? 1 : 0;
2170a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                invalidateHwcGeometry();
2171a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                repaintEverything();
2172a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                return NO_ERROR;
2173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1010:  // interrogate.
217401b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian                reply->writeInt32(0);
2175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(0);
2176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(mDebugRegion);
2177b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                reply->writeInt32(0);
217812839bee29bdcc65731b4d42029cc59e2320c5c4Dianne Hackborn                reply->writeInt32(mDebugDisableHWC);
2179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
2180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1013: {
2181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                Mutex::Autolock _l(mStateLock);
21824297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                sp<const DisplayDevice> hw(getDefaultDisplayDevice());
21834297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                reply->writeInt32(hw->getPageFlipCount());
2184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
2185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return NO_ERROR;
2186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
2187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return err;
2189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
219153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopianvoid SurfaceFlinger::repaintEverything() {
219287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    android_atomic_or(1, &mRepaintEverything);
219399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    signalTransaction();
219453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian}
219553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian
219659119e658a12279e8fff508f8773843de2d90917Mathias Agopian// ---------------------------------------------------------------------------
219759119e658a12279e8fff508f8773843de2d90917Mathias Agopian
21983ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopianstatus_t SurfaceFlinger::renderScreenToTexture(uint32_t layerStack,
2199118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        GLuint* textureName, GLfloat* uOut, GLfloat* vOut)
2200118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{
2201118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    Mutex::Autolock _l(mStateLock);
22023ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    return renderScreenToTextureLocked(layerStack, textureName, uOut, vOut);
2203118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
2204118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
22053ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopianstatus_t SurfaceFlinger::renderScreenToTextureLocked(uint32_t layerStack,
22069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        GLuint* textureName, GLfloat* uOut, GLfloat* vOut)
220759119e658a12279e8fff508f8773843de2d90917Mathias Agopian{
220822ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian    ATRACE_CALL();
220922ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian
221059119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
221159119e658a12279e8fff508f8773843de2d90917Mathias Agopian        return INVALID_OPERATION;
221259119e658a12279e8fff508f8773843de2d90917Mathias Agopian
221359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // get screen geometry
22143ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    // FIXME: figure out what it means to have a screenshot texture w/ multi-display
22153ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    sp<const DisplayDevice> hw(getDefaultDisplayDevice());
22164297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const uint32_t hw_w = hw->getWidth();
22174297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const uint32_t hw_h = hw->getHeight();
221859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLfloat u = 1;
221959119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLfloat v = 1;
222059119e658a12279e8fff508f8773843de2d90917Mathias Agopian
222159119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // make sure to clear all GL error flags
222259119e658a12279e8fff508f8773843de2d90917Mathias Agopian    while ( glGetError() != GL_NO_ERROR ) ;
222359119e658a12279e8fff508f8773843de2d90917Mathias Agopian
222459119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // create a FBO
222559119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLuint name, tname;
222659119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glGenTextures(1, &tname);
222759119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
2228a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2229a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
22309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
22319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            hw_w, hw_h, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
223259119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (glGetError() != GL_NO_ERROR) {
2233015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian        while ( glGetError() != GL_NO_ERROR ) ;
223459119e658a12279e8fff508f8773843de2d90917Mathias Agopian        GLint tw = (2 << (31 - clz(hw_w)));
223559119e658a12279e8fff508f8773843de2d90917Mathias Agopian        GLint th = (2 << (31 - clz(hw_h)));
22369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
22379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian                tw, th, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
223859119e658a12279e8fff508f8773843de2d90917Mathias Agopian        u = GLfloat(hw_w) / tw;
223959119e658a12279e8fff508f8773843de2d90917Mathias Agopian        v = GLfloat(hw_h) / th;
224059119e658a12279e8fff508f8773843de2d90917Mathias Agopian    }
224159119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glGenFramebuffersOES(1, &name);
224259119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
22439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES,
22449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0);
224559119e658a12279e8fff508f8773843de2d90917Mathias Agopian
22469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // redraw the screen entirely...
2247c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_EXTERNAL_OES);
2248c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_2D);
22499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glClearColor(0,0,0,1);
22509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glClear(GL_COLOR_BUFFER_BIT);
2251a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glMatrixMode(GL_MODELVIEW);
2252a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glLoadIdentity();
22534297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const Vector< sp<LayerBase> >& layers(hw->getVisibleLayersSortedByZ());
22549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const size_t count = layers.size();
22559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (size_t i=0 ; i<count ; ++i) {
22569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
2257fcb239d3dac8bc80f28177f1951611c1d43286ffMathias Agopian        layer->draw(hw);
22589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
225959119e658a12279e8fff508f8773843de2d90917Mathias Agopian
22604297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->compositionComplete();
2261118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
22629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // back to main framebuffer
22639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
22649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDeleteFramebuffersOES(1, &name);
226559119e658a12279e8fff508f8773843de2d90917Mathias Agopian
22669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *textureName = tname;
22679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *uOut = u;
22689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *vOut = v;
22699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
22709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
227159119e658a12279e8fff508f8773843de2d90917Mathias Agopian
22729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// ---------------------------------------------------------------------------
22739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22749d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brownstatus_t SurfaceFlinger::captureScreenImplLocked(const sp<IBinder>& display,
227574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        sp<IMemoryHeap>* heap,
227674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t* w, uint32_t* h, PixelFormat* f,
2277bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t sw, uint32_t sh,
2278bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ, uint32_t maxLayerZ)
227974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{
2280fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian    ATRACE_CALL();
2281fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian
228274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    status_t result = PERMISSION_DENIED;
228374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
22843b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject()) {
228574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return INVALID_OPERATION;
22863b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
228774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
228874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // get screen geometry
22893ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    sp<const DisplayDevice> hw(getDisplayDevice(display));
22904297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const uint32_t hw_w = hw->getWidth();
22914297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const uint32_t hw_h = hw->getHeight();
229274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
22933b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    // if we have secure windows on this display, never allow the screen capture
22944297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    if (hw->getSecureLayerVisible()) {
2295ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian        ALOGW("FB is protected: PERMISSION_DENIED");
22963b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        return PERMISSION_DENIED;
22973b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
22983b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
22993b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    if ((sw > hw_w) || (sh > hw_h)) {
2300ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian        ALOGE("size mismatch (%d, %d) > (%d, %d)", sw, sh, hw_w, hw_h);
230174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return BAD_VALUE;
23023b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
230374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
230474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    sw = (!sw) ? hw_w : sw;
230574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    sh = (!sh) ? hw_h : sh;
230674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const size_t size = sw * sh * 4;
2307fcb239d3dac8bc80f28177f1951611c1d43286ffMathias Agopian    const bool filtering = sw != hw_w || sh != hw_h;
230874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
2309ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian//    ALOGD("screenshot: sw=%d, sh=%d, minZ=%d, maxZ=%d",
2310ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian//            sw, sh, minLayerZ, maxLayerZ);
2311c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
231274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // make sure to clear all GL error flags
231374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    while ( glGetError() != GL_NO_ERROR ) ;
231474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
231574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // create a FBO
231674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    GLuint name, tname;
231774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glGenRenderbuffersOES(1, &tname);
231874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindRenderbufferOES(GL_RENDERBUFFER_OES, tname);
231974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA8_OES, sw, sh);
2320fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian
232174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glGenFramebuffersOES(1, &name);
232274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
232374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES,
232474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, tname);
232574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
232674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
2327c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
232874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    if (status == GL_FRAMEBUFFER_COMPLETE_OES) {
232974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
233074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // invert everything, b/c glReadPixel() below will invert the FB
233174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glViewport(0, 0, sw, sh);
233274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_PROJECTION);
233374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glPushMatrix();
233474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glLoadIdentity();
2335ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian        glOrthof(0, hw_w, hw_h, 0, 0, 1);
233674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_MODELVIEW);
233774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
233874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // redraw the screen entirely...
233974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glClearColor(0,0,0,1);
234074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
2341f653b897a449e10d6cbfb6e0812f7b0bb02d6482Mathias Agopian
23423ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian        const Vector< sp<LayerBase> >& layers(hw->getVisibleLayersSortedByZ());
23439575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        const size_t count = layers.size();
234474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        for (size_t i=0 ; i<count ; ++i) {
234574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            const sp<LayerBase>& layer(layers[i]);
23463ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian            const uint32_t z = layer->drawingState().z;
23473ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian            if (z >= minLayerZ && z <= maxLayerZ) {
23483ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian                if (filtering) layer->setFiltering(true);
23493ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian                layer->draw(hw);
23503ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian                if (filtering) layer->setFiltering(false);
2351bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian            }
235274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        }
235374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
235474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // check for errors and return screen capture
235574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        if (glGetError() != GL_NO_ERROR) {
235674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // error while rendering
235774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            result = INVALID_OPERATION;
235874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        } else {
235974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // allocate shared memory large enough to hold the
236074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // screen capture
236174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            sp<MemoryHeapBase> base(
236274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    new MemoryHeapBase(size, 0, "screen-capture") );
236374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            void* const ptr = base->getBase();
236474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            if (ptr) {
236574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                // capture the screen with glReadPixels()
2366fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian                ScopedTrace _t(ATRACE_TAG, "glReadPixels");
236774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                glReadPixels(0, 0, sw, sh, GL_RGBA, GL_UNSIGNED_BYTE, ptr);
236874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                if (glGetError() == GL_NO_ERROR) {
236974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *heap = base;
237074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *w = sw;
237174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *h = sh;
237274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *f = PIXEL_FORMAT_RGBA_8888;
237374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    result = NO_ERROR;
237474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                }
237574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            } else {
237674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                result = NO_MEMORY;
237774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            }
237874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        }
237974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glViewport(0, 0, hw_w, hw_h);
238074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_PROJECTION);
238174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glPopMatrix();
238274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_MODELVIEW);
238374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    } else {
238474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        result = BAD_VALUE;
238574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    }
238674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
238774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // release FBO resources
238874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
238974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glDeleteRenderbuffersOES(1, &tname);
239074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glDeleteFramebuffersOES(1, &name);
2391e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian
23924297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->compositionComplete();
2393e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian
2394ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian//    ALOGD("screenshot: result = %s", result<0 ? strerror(result) : "OK");
2395c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
239674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    return result;
239774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian}
239874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
239974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
24009d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brownstatus_t SurfaceFlinger::captureScreen(const sp<IBinder>& display,
24011b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        sp<IMemoryHeap>* heap,
240274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t* width, uint32_t* height, PixelFormat* format,
2403bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t sw, uint32_t sh,
2404bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ, uint32_t maxLayerZ)
24051b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian{
24069d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown    if (CC_UNLIKELY(display == 0))
24071b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        return BAD_VALUE;
24081b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
24091b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
24101b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        return INVALID_OPERATION;
24111b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
24121b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    class MessageCaptureScreen : public MessageBase {
24131b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        SurfaceFlinger* flinger;
24149d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown        sp<IBinder> display;
24151b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        sp<IMemoryHeap>* heap;
24161b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        uint32_t* w;
24171b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        uint32_t* h;
24181b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        PixelFormat* f;
241974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t sw;
242074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t sh;
2421bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ;
2422bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t maxLayerZ;
24231b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        status_t result;
24241b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    public:
24259d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown        MessageCaptureScreen(SurfaceFlinger* flinger, const sp<IBinder>& display,
242674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                sp<IMemoryHeap>* heap, uint32_t* w, uint32_t* h, PixelFormat* f,
2427bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                uint32_t sw, uint32_t sh,
2428bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                uint32_t minLayerZ, uint32_t maxLayerZ)
24299d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown            : flinger(flinger), display(display),
2430bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              heap(heap), w(w), h(h), f(f), sw(sw), sh(sh),
2431bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              minLayerZ(minLayerZ), maxLayerZ(maxLayerZ),
2432bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              result(PERMISSION_DENIED)
24331b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
24341b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
24351b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        status_t getResult() const {
24361b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            return result;
24371b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
24381b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        virtual bool handler() {
24391b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
24409d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown            result = flinger->captureScreenImplLocked(display,
2441bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                    heap, w, h, f, sw, sh, minLayerZ, maxLayerZ);
24421b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            return true;
24431b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
24441b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    };
24451b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
24461b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    sp<MessageBase> msg = new MessageCaptureScreen(this,
24479d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown            display, heap, width, height, format, sw, sh, minLayerZ, maxLayerZ);
24481b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    status_t res = postMessageSync(msg);
24491b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    if (res == NO_ERROR) {
24501b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        res = static_cast<MessageCaptureScreen*>( msg.get() )->getResult();
24511b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    }
24521b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    return res;
24531b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian}
24541b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
24551b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// ---------------------------------------------------------------------------
24561b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
2457921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::LayerVector::LayerVector() {
2458921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
2459921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
2460921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::LayerVector::LayerVector(const LayerVector& rhs)
2461921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    : SortedVector<sp<LayerBase> >(rhs) {
2462921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
2463921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
2464921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianint SurfaceFlinger::LayerVector::do_compare(const void* lhs,
2465921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    const void* rhs) const
2466edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2467be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    // sort layers per layer-stack, then by z-order and finally by sequence
2468921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    const sp<LayerBase>& l(*reinterpret_cast<const sp<LayerBase>*>(lhs));
2469921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    const sp<LayerBase>& r(*reinterpret_cast<const sp<LayerBase>*>(rhs));
2470be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian
2471be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    uint32_t ls = l->currentState().layerStack;
2472be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    uint32_t rs = r->currentState().layerStack;
2473be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    if (ls != rs)
2474be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian        return ls - rs;
2475be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian
2476921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    uint32_t lz = l->currentState().z;
2477921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    uint32_t rz = r->currentState().z;
2478be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    if (lz != rz)
2479be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian        return lz - rz;
2480be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian
2481be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    return l->sequence - r->sequence;
2482921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
2483921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
2484921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian// ---------------------------------------------------------------------------
2485921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
24863ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias AgopianSurfaceFlinger::DisplayDeviceState::DisplayDeviceState()
24873ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    : type(DisplayDevice::DISPLAY_ID_INVALID) {
2488e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
2489e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
24903ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias AgopianSurfaceFlinger::DisplayDeviceState::DisplayDeviceState(DisplayDevice::DisplayType type)
24913ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    : type(type), layerStack(0), orientation(0) {
2492da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian    viewport.makeInvalid();
2493da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian    frame.makeInvalid();
2494b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
24957303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
2496b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// ---------------------------------------------------------------------------
249796f0819f81293076e652792794a961543e6750d7Mathias Agopian
24989a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::GraphicBufferAlloc() {}
24999a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
25009a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::~GraphicBufferAlloc() {}
25019a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
25029a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h,
2503d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        PixelFormat format, uint32_t usage, status_t* error) {
25049a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(w, h, format, usage));
25059a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    status_t err = graphicBuffer->initCheck();
2506d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian    *error = err;
2507a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (err != 0 || graphicBuffer->handle == 0) {
2508d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        if (err == NO_MEMORY) {
2509d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian            GraphicBuffer::dumpAllocationsToSystemLog();
2510d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        }
2511e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE("GraphicBufferAlloc::createGraphicBuffer(w=%d, h=%d) "
2512a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian             "failed (%s), handle=%p",
2513a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                w, h, strerror(-err), graphicBuffer->handle);
25149a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis        return 0;
25159a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    }
25169a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    return graphicBuffer;
25179a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis}
25189a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
25199a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis// ---------------------------------------------------------------------------
25209a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
2521edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
2522