SurfaceFlinger.cpp revision 303d538bb012e82c6b9a98c4930a03455000f761
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
17edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdlib.h>
18edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdio.h>
19edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdint.h>
20edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <unistd.h>
21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <fcntl.h>
22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <errno.h>
23edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <math.h>
24a837ba778f2d7a5170b37aa33624d9b9711c354dJean-Baptiste Queru#include <limits.h>
25edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/types.h>
26edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/stat.h>
27edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/ioctl.h>
28edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/log.h>
30edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/properties.h>
31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
32c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IPCThreadState.h>
33c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IServiceManager.h>
347303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian#include <binder/MemoryHeapBase.h>
3599b49840d309727678b77403d6cc9f920111623fMathias Agopian#include <binder/PermissionCache.h>
367303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
37d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian#include <gui/IDisplayEventConnection.h>
38d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
39edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String8.h>
40edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String16.h>
41edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/StopWatch.h>
42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
433330b203039dea366d4981db1408a460134b2d2cMathias Agopian#include <ui/GraphicBufferAllocator.h>
44edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/PixelFormat.h>
45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <pixelflinger/pixelflinger.h>
47edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <GLES/gl.h>
48edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h"
50d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian#include "DisplayEventConnection.h"
51d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian#include "EventThread.h"
521f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian#include "GLExtensions.h"
538afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian#include "DdmConnection.h"
54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h"
55edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerDim.h"
56118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian#include "LayerScreenshot.h"
57edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h"
58edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "DisplayHardware/DisplayHardware.h"
60a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian#include "DisplayHardware/HWComposer.h"
61edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
621db13d79518f600d65a4fc006fe42900b890966eGlenn Kasten#include <private/android_filesystem_config.h>
63a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian#include <private/surfaceflinger/SharedBufferStack.h>
64a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
65bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian#define EGL_VERSION_HW_ANDROID  0x3143
66bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
67edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DISPLAY_COUNT       1
68edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
7299b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sHardwareTest("android.permission.HARDWARE_TEST");
7399b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER");
7499b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER");
7599b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sDump("android.permission.DUMP");
7699b49840d309727678b77403d6cc9f920111623fMathias Agopian
7799b49840d309727678b77403d6cc9f920111623fMathias Agopian// ---------------------------------------------------------------------------
7899b49840d309727678b77403d6cc9f920111623fMathias Agopian
79edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::SurfaceFlinger()
80edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    :   BnSurfaceComposer(), Thread(false),
81edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mTransactionFlags(0),
8228378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        mTransationPending(false),
83076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved(false),
84edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mBootTime(systemTime()),
85edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mVisibleRegionsDirty(false),
86a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        mHwWorkListDirty(false),
87abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        mElectronBeamAnimationMode(0),
88edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDebugRegion(0),
89edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDebugBackground(0),
908afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian        mDebugDDMS(0),
9173d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian        mDebugDisableHWC(0),
92a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian        mDebugDisableTransformHint(0),
939795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInSwapBuffers(0),
949795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastSwapBufferTime(0),
959795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInTransaction(0),
969795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastTransactionTime(0),
973330b203039dea366d4981db1408a460134b2d2cMathias Agopian        mBootFinished(false),
98edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mConsoleSignals(0),
99edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mSecureFrameBuffer(0)
100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    init();
102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::init()
105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
106a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI("SurfaceFlinger is starting");
107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // debugging stuff...
109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char value[PROPERTY_VALUE_MAX];
1108afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    property_get("debug.sf.showupdates", value, "0");
112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDebugRegion = atoi(value);
1138afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    property_get("debug.sf.showbackground", value, "0");
115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDebugBackground = atoi(value);
116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1178afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    property_get("debug.sf.ddms", value, "0");
1188afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    mDebugDDMS = atoi(value);
1198afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    if (mDebugDDMS) {
1208afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian        DdmConnection::start(getServiceName());
1218afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    }
1228afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
123a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI_IF(mDebugRegion,       "showupdates enabled");
124a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI_IF(mDebugBackground,   "showbackground enabled");
125a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI_IF(mDebugDDMS,         "DDMS debugging enabled");
126edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
127edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
12899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::onFirstRef()
12999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
13099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.init(this);
13199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
13299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY);
13399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
13499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // Wait for the main thread to be done with its initialization
13599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mReadyToRunBarrier.wait();
13699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
13799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
13899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::~SurfaceFlinger()
140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
141edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDeleteTextures(1, &mWormholeTexName);
142edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
143edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
14499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::binderDied(const wp<IBinder>& who)
14599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
14699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // the window manager died on us. prepare its eulogy.
14799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
14899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // reset screen orientation
14999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    Vector<ComposerState> state;
15099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    setTransactionState(state, eOrientationDefault, 0);
15199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
15299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // restart the boot-animation
15399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    property_set("ctl.start", "bootanim");
15499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
15599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
1567303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopiansp<IMemoryHeap> SurfaceFlinger::getCblk() const
157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1587303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    return mServerHeap;
159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1617e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopiansp<ISurfaceComposerClient> SurfaceFlinger::createConnection()
162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
16396f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<ISurfaceComposerClient> bclient;
16496f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<Client> client(new Client(this));
16596f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = client->initCheck();
16696f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR) {
16796f0819f81293076e652792794a961543e6750d7Mathias Agopian        bclient = client;
168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return bclient;
170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1729a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc()
1739a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis{
1749a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc());
1759a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    return gba;
1769a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis}
177b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst GraphicPlane& SurfaceFlinger::graphicPlane(int dpy) const
179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
180e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block    ALOGE_IF(uint32_t(dpy) >= DISPLAY_COUNT, "Invalid DisplayID %d", dpy);
181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(mGraphicPlanes[dpy]);
182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return plane;
183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane& SurfaceFlinger::graphicPlane(int dpy)
186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return const_cast<GraphicPlane&>(
188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const_cast<SurfaceFlinger const *>(this)->graphicPlane(dpy));
189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::bootFinished()
192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t now = systemTime();
194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t duration = now - mBootTime;
195a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
1963330b203039dea366d4981db1408a460134b2d2cMathias Agopian    mBootFinished = true;
1971f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
1981f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // wait patiently for the window manager death
1991f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    const String16 name("window");
2001f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    sp<IBinder> window(defaultServiceManager()->getService(name));
2011f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    if (window != 0) {
2021f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian        window->linkToDeath(this);
2031f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    }
2041f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
2051f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // stop boot animation
206a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    property_set("ctl.stop", "bootanim");
207edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
209edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic inline uint16_t pack565(int r, int g, int b) {
210edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return (r<<11)|(g<<5)|b;
211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::readyToRun()
214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
215a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI(   "SurfaceFlinger's main thread ready to run. "
216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            "Initializing graphics H/W...");
217edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // we only support one display currently
219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int dpy = 0;
220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    {
222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // initialize the main display
223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GraphicPlane& plane(graphicPlane(dpy));
224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        DisplayHardware* const hw = new DisplayHardware(this, dpy);
225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        plane.setDisplayHardware(hw);
226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2287303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    // create the shared control-block
2297303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    mServerHeap = new MemoryHeapBase(4096,
2307303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian            MemoryHeapBase::READ_ONLY, "SurfaceFlinger read-only heap");
231e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block    ALOGE_IF(mServerHeap==0, "can't create shared memory dealer");
2328b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
2337303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    mServerCblk = static_cast<surface_flinger_cblk_t*>(mServerHeap->getBase());
234e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block    ALOGE_IF(mServerCblk==0, "can't get to shared control block's address");
2358b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
2367303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    new(mServerCblk) surface_flinger_cblk_t;
2377303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize primary screen
239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // (other display should be initialized in the same manner, but
240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // asynchronously, as they could come and go. None of this is supported
241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // yet).
242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(graphicPlane(dpy));
243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw = plane.displayHardware();
244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint32_t w = hw.getWidth();
245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint32_t h = hw.getHeight();
246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint32_t f = hw.getFormat();
247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    hw.makeCurrent();
248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize the shared control block
250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mServerCblk->connected |= 1<<dpy;
251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    display_cblk_t* dcblk = mServerCblk->displays + dpy;
252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    memset(dcblk, 0, sizeof(display_cblk_t));
2532b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    dcblk->w            = plane.getWidth();
2542b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    dcblk->h            = plane.getHeight();
255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->format       = f;
256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->orientation  = ISurfaceComposer::eOrientationDefault;
257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->xdpi         = hw.getDpiX();
258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->ydpi         = hw.getDpiY();
259edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->fps          = hw.getRefreshRate();
260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->density      = hw.getDensity();
261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // Initialize OpenGL|ES
263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
2648b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber    glPixelStorei(GL_PACK_ALIGNMENT, 4);
265edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glEnableClientState(GL_VERTEX_ARRAY);
266edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glEnable(GL_SCISSOR_TEST);
267edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glShadeModel(GL_FLAT);
268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_DITHER);
269edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_CULL_FACE);
270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint16_t g0 = pack565(0x0F,0x1F,0x0F);
272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint16_t g1 = pack565(0x17,0x2f,0x17);
2739575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    const uint16_t wormholeTexData[4] = { g0, g1, g1, g0 };
274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glGenTextures(1, &mWormholeTexName);
275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glBindTexture(GL_TEXTURE_2D, mWormholeTexName);
276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
278edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0,
2819575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis            GL_RGB, GL_UNSIGNED_SHORT_5_6_5, wormholeTexData);
2829575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis
2839575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    const uint16_t protTexData[] = { pack565(0x03, 0x03, 0x03) };
2849575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glGenTextures(1, &mProtectedTexName);
2859575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glBindTexture(GL_TEXTURE_2D, mProtectedTexName);
2869575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2879575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2889575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
2899575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
2909575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0,
2919575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis            GL_RGB, GL_UNSIGNED_SHORT_5_6_5, protTexData);
292edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
293edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glViewport(0, 0, w, h);
294edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glMatrixMode(GL_PROJECTION);
295edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glLoadIdentity();
296ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    // put the origin in the left-bottom corner
297ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    glOrthof(0, w, 0, h, 0, 1); // l=0, r=w ; b=0, t=h
298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
299d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
300d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian    // start the EventThread
301d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian    mEventThread = new EventThread(this);
3028aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian    mEventQueue.setEventThread(mEventThread);
303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     *  We're now ready to accept clients...
306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
308d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian    mReadyToRunBarrier.open();
309d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
310a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    // start boot animation
311a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    property_set("ctl.start", "bootanim");
3128b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
313edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
314edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
315edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
317d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
318582270d69db94286a248bd829f1ae6f910d45124Jamie Gennisbool SurfaceFlinger::authenticateSurfaceTexture(
319582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis        const sp<ISurfaceTexture>& surfaceTexture) const {
320134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    Mutex::Autolock _l(mStateLock);
321582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis    sp<IBinder> surfaceTextureBinder(surfaceTexture->asBinder());
322134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
323134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // Check the visible layer list for the ISurface
324134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
325134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    size_t count = currentLayers.size();
326134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    for (size_t i=0 ; i<count ; i++) {
327134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        const sp<LayerBase>& layer(currentLayers[i]);
328134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        sp<LayerBaseClient> lbc(layer->getLayerBaseClient());
329582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis        if (lbc != NULL) {
330582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder();
331582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            if (lbcBinder == surfaceTextureBinder) {
332582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis                return true;
333582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            }
334134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        }
335134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    }
336134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
337134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // Check the layers in the purgatory.  This check is here so that if a
338582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis    // SurfaceTexture gets destroyed before all the clients are done using it,
339582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis    // the error will not be reported as "surface XYZ is not authenticated", but
340134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // will instead fail later on when the client tries to use the surface,
341134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // which should be reported as "surface XYZ returned an -ENODEV".  The
342134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // purgatorized layers are no less authentic than the visible ones, so this
343134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // should not cause any harm.
344134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    size_t purgatorySize =  mLayerPurgatory.size();
345134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    for (size_t i=0 ; i<purgatorySize ; i++) {
346134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
347134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        sp<LayerBaseClient> lbc(layer->getLayerBaseClient());
348582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis        if (lbc != NULL) {
349582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder();
350582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            if (lbcBinder == surfaceTextureBinder) {
351582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis                return true;
352582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            }
353134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        }
354134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    }
355134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
356134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    return false;
357134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis}
358134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
359d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian// ----------------------------------------------------------------------------
360d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
361d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopiansp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection() {
3628aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian    return mEventThread->createEventConnection();
363bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian}
364bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
365edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
36699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
36799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::waitForEvent() {
36899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.waitMessage();
36999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
37099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
37199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalTransaction() {
37299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.invalidate();
37399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
37499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
37599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalLayerUpdate() {
37699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.invalidate();
37799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
37899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
37999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalRefresh() {
38099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.refresh();
38199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
38299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
38399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg,
38499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        nsecs_t reltime, uint32_t flags) {
38599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return mEventQueue.postMessage(msg, reltime);
38699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
38799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
38899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,
38999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        nsecs_t reltime, uint32_t flags) {
39099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    status_t res = mEventQueue.postMessage(msg, reltime);
39199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    if (res == NO_ERROR) {
39299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        msg->wait();
39399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    }
39499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return res;
39599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
396edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
397edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool SurfaceFlinger::threadLoop()
398edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
399edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    waitForEvent();
40099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return true;
40199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
402edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
40399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::onMessageReceived(int32_t what)
40499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
40599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    switch (what) {
406303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian        case MessageQueue::REFRESH: {
407303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian//        case MessageQueue::INVALIDATE: {
40899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            // check for transactions
40999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            if (CC_UNLIKELY(mConsoleSignals)) {
41099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian                handleConsoleEvents();
41199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            }
412edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
41399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            // if we're in a global transaction, don't do anything.
41499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
41599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            uint32_t transactionFlags = peekTransactionFlags(mask);
41699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            if (CC_UNLIKELY(transactionFlags)) {
41799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian                handleTransaction(transactionFlags);
41899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            }
419edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
42099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            // post surfaces (if needed)
42199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            handlePageFlip();
422edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
423303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian//            signalRefresh();
424303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian//
425303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian//        } break;
426303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian//
427303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian//        case MessageQueue::REFRESH: {
4283a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian
429c9ca7011501cb8730ce4e6e527cb402adb7a0178Mathias Agopian            handleRefresh();
430a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
431303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian            const DisplayHardware& hw(graphicPlane(0).displayHardware());
432303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian
433303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian//            if (mDirtyRegion.isEmpty()) {
434303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian//                return;
435303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian//            }
436303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian
437b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian            if (CC_UNLIKELY(mHwWorkListDirty)) {
438b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian                // build the h/w work list
439b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian                handleWorkList();
440b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian            }
441303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian
442b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian            if (CC_LIKELY(hw.canDraw())) {
443b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian                // repaint the framebuffer (if needed)
444b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian                handleRepaint();
445b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian                // inform the h/w that we're done compositing
446b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian                hw.compositionComplete();
447b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian                postFramebuffer();
448c9ca7011501cb8730ce4e6e527cb402adb7a0178Mathias Agopian            } else {
449b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian                // pretend we did the post
450c9ca7011501cb8730ce4e6e527cb402adb7a0178Mathias Agopian                hw.compositionComplete();
45199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            }
452b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian
45399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        } break;
454edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
455edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
456edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
457edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer()
458edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
459b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian    // mSwapRegion can be empty here is some cases, for instance if a hidden
460b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian    // or fully transparent window is updating.
461b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian    // in that case, we need to flip anyways to not risk a deadlock with
462b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian    // h/w composer.
463b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian
464a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
465a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    const nsecs_t now = systemTime();
466a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = now;
467a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    hw.flip(mSwapRegion);
468e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
469e8696a40e09b24b634214684d18526187b316a2fJamie Gennis    size_t numLayers = mVisibleLayersSortedByZ.size();
470e8696a40e09b24b634214684d18526187b316a2fJamie Gennis    for (size_t i = 0; i < numLayers; i++) {
471e8696a40e09b24b634214684d18526187b316a2fJamie Gennis        mVisibleLayersSortedByZ[i]->onLayerDisplayed();
472e8696a40e09b24b634214684d18526187b316a2fJamie Gennis    }
473e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
474a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mLastSwapBufferTime = systemTime() - now;
475a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = 0;
476a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mSwapRegion.clear();
477edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
478edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
479edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleConsoleEvents()
480edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
481edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // something to do with the console
482edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw = graphicPlane(0).displayHardware();
483edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
484edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int what = android_atomic_and(0, &mConsoleSignals);
485edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (what & eConsoleAcquired) {
486edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        hw.acquireScreen();
4879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // this is a temporary work-around, eventually this should be called
4889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // by the power-manager
489abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        SurfaceFlinger::turnElectronBeamOn(mElectronBeamAnimationMode);
490edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
491edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
492edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (what & eConsoleReleased) {
49359119e658a12279e8fff508f8773843de2d90917Mathias Agopian        if (hw.isScreenAcquired()) {
494edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            hw.releaseScreen();
495edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
496edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
497edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
498edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDirtyRegion.set(hw.bounds());
499edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
500edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
501edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
502edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
503ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    Mutex::Autolock _l(mStateLock);
504ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    const nsecs_t now = systemTime();
505ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = now;
506ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
507ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // Here we're guaranteed that some transaction flags are set
508ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // so we can call handleTransactionLocked() unconditionally.
509ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // We call getTransactionFlags(), which will also clear the flags,
510ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // with mStateLock held to guarantee that mCurrentState won't change
511ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // until the transaction is committed.
512ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
513ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
514ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    transactionFlags = getTransactionFlags(mask);
515ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    handleTransactionLocked(transactionFlags);
516ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
517ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mLastTransactionTime = systemTime() - now;
518ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = 0;
519ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    invalidateHwcGeometry();
520ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // here the transaction has been committed
5213d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian}
522edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
523ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopianvoid SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
5243d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{
5253d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    const LayerVector& currentLayers(mCurrentState.layersSortedByZ);
526edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t count = currentLayers.size();
527edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
528edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
529edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Traversal of the children
530edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * (perform the transaction for each of them if needed)
531edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
532edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
533edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const bool layersNeedTransaction = transactionFlags & eTraversalNeeded;
534edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (layersNeedTransaction) {
535edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (size_t i=0 ; i<count ; i++) {
536076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            const sp<LayerBase>& layer = currentLayers[i];
537edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
538edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (!trFlags) continue;
539edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
540edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const uint32_t flags = layer->doTransaction(0);
541edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (flags & Layer::eVisibleRegion)
542edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mVisibleRegionsDirty = true;
543edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
544edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
545edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
546edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
547edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Perform our own transaction if needed
548edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
549edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
550edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (transactionFlags & eTransactionNeeded) {
551edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (mCurrentState.orientation != mDrawingState.orientation) {
552edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // the orientation has changed, recompute all visible regions
553edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // and invalidate everything.
554edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
555edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int dpy = 0;
556edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int orientation = mCurrentState.orientation;
55721230c6410bdab13cd2bd274da54b1e4061b6035Jeff Brown            // Currently unused: const uint32_t flags = mCurrentState.orientationFlags;
558edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            GraphicPlane& plane(graphicPlane(dpy));
559edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            plane.setOrientation(orientation);
560edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
561edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // update the shared control block
562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const DisplayHardware& hw(plane.displayHardware());
563edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            volatile display_cblk_t* dcblk = mServerCblk->displays + dpy;
564edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dcblk->orientation = orientation;
5652b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            dcblk->w = plane.getWidth();
5662b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            dcblk->h = plane.getHeight();
567edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
568edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
569edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mDirtyRegion.set(hw.bounds());
570edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
571edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5720aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        if (currentLayers.size() > mDrawingState.layersSortedByZ.size()) {
5730aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            // layers have been added
574edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
575edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
576edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5770aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        // some layers might have been removed, so
5780aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        // we need to update the regions they're exposing.
5790aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        if (mLayersRemoved) {
58048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian            mLayersRemoved = false;
581edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
5820aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            const LayerVector& previousLayers(mDrawingState.layersSortedByZ);
5833d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian            const size_t count = previousLayers.size();
5843d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian            for (size_t i=0 ; i<count ; i++) {
5850aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                const sp<LayerBase>& layer(previousLayers[i]);
5860aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                if (currentLayers.indexOf( layer ) < 0) {
5870aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                    // this layer is not visible anymore
5885d7126b625c8c4a7b945e8c247b63abff7bc13b6Mathias Agopian                    mDirtyRegionRemovedLayer.orSelf(layer->visibleRegionScreen);
5890aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                }
5900aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            }
591edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
592edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
593edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
594edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    commitTransaction();
595edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
596edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
597edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::computeVisibleRegions(
5981bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian    const LayerVector& currentLayers, Region& dirtyRegion, Region& opaqueRegion)
599edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
600edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(graphicPlane(0));
601edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Transform& planeTransform(plane.transform());
602ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian    const DisplayHardware& hw(plane.displayHardware());
603ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian    const Region screenRegion(hw.bounds());
604edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
605edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveOpaqueLayers;
606edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveCoveredLayers;
607edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region dirty;
608edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
609edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    bool secureFrameBuffer = false;
610edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
611edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t i = currentLayers.size();
612edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    while (i--) {
613076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        const sp<LayerBase>& layer = currentLayers[i];
614edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->validateVisibility(planeTransform);
615edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
616edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // start with the whole surface at its current location
617970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian        const Layer::State& s(layer->drawingState());
618edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
619ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
620ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * opaqueRegion: area of a surface that is fully opaque.
621ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
622edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region opaqueRegion;
623ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
624ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
625ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visibleRegion: area of a surface that is visible on screen
626ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * and not fully transparent. This is essentially the layer's
627ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * footprint minus the opaque regions above it.
628ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * Areas covered by a translucent surface are considered visible.
629ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
630edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region visibleRegion;
631ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
632ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
633ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * coveredRegion: area of a surface that is covered by all
634ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visible regions above it (which includes the translucent areas).
635ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
636edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region coveredRegion;
637ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
638ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
639ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // handle hidden surfaces by setting the visible region to empty
64099ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten        if (CC_LIKELY(!(s.flags & ISurfaceComposer::eLayerHidden) && s.alpha)) {
641a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            const bool translucent = !layer->isOpaque();
642970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian            const Rect bounds(layer->visibleBounds());
643edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            visibleRegion.set(bounds);
644ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            visibleRegion.andSelf(screenRegion);
645ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            if (!visibleRegion.isEmpty()) {
646ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // Remove the transparent area from the visible region
647ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (translucent) {
648ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    visibleRegion.subtractSelf(layer->transparentRegionScreen);
649ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
650edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
651ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // compute the opaque region
652ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                const int32_t layerOrientation = layer->getOrientation();
653ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (s.alpha==255 && !translucent &&
654ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                        ((layerOrientation & Transform::ROT_INVALID) == false)) {
655ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    // the opaque region is the layer's footprint
656ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    opaqueRegion = visibleRegion;
657ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
658edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
659edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
660edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
661ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Clip the covered region to the visible region
662ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        coveredRegion = aboveCoveredLayers.intersect(visibleRegion);
663ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
664ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveCoveredLayers for next (lower) layer
665ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        aboveCoveredLayers.orSelf(visibleRegion);
666ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
667edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // subtract the opaque region covered by the layers above us
668edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        visibleRegion.subtractSelf(aboveOpaqueLayers);
669edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
670edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // compute this layer's dirty region
671edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (layer->contentDirty) {
672edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // we need to invalidate the whole region
673edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dirty = visibleRegion;
674edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // as well, as the old visible region
675edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dirty.orSelf(layer->visibleRegionScreen);
676edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->contentDirty = false;
677edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
678a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian            /* compute the exposed region:
679ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   the exposed region consists of two components:
680ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   1) what's VISIBLE now and was COVERED before
681ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   2) what's EXPOSED now less what was EXPOSED before
682ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
683ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * note that (1) is conservative, we start with the whole
684ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * visible region but only keep what used to be covered by
685ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * something -- which mean it may have been exposed.
686ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
687ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * (2) handles areas that were not covered by anything but got
688ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * exposed because of a resize.
689a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian             */
690ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region newExposed = visibleRegion - coveredRegion;
691ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldVisibleRegion = layer->visibleRegionScreen;
692ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldCoveredRegion = layer->coveredRegionScreen;
693ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldExposed = oldVisibleRegion - oldCoveredRegion;
694ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed);
695edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
696edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirty.subtractSelf(aboveOpaqueLayers);
697edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
698edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // accumulate to the screen dirty region
699edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirtyRegion.orSelf(dirty);
700edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
701ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveOpaqueLayers for next (lower) layer
702edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        aboveOpaqueLayers.orSelf(opaqueRegion);
7038b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
704edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // Store the visible region is screen space
705edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setVisibleRegion(visibleRegion);
706edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setCoveredRegion(coveredRegion);
707edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
708970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian        // If a secure layer is partially visible, lock-down the screen!
709edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (layer->isSecure() && !visibleRegion.isEmpty()) {
710edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            secureFrameBuffer = true;
711edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
712edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
713edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
714970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian    // invalidate the areas where a layer was removed
715970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian    dirtyRegion.orSelf(mDirtyRegionRemovedLayer);
716970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian    mDirtyRegionRemovedLayer.clear();
717970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian
718edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mSecureFrameBuffer = secureFrameBuffer;
719edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    opaqueRegion = aboveOpaqueLayers;
720edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
721edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
722edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
723edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::commitTransaction()
724edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
7252f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall    if (!mLayersPendingRemoval.isEmpty()) {
7262f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall        // Notify removed layers now that they can't be drawn from
7272f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall        for (size_t i = 0; i < mLayersPendingRemoval.size(); i++) {
7282f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall            mLayersPendingRemoval[i]->onRemoved();
7292f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall        }
7302f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall        mLayersPendingRemoval.clear();
7312f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall    }
7322f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall
733edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDrawingState = mCurrentState;
73428378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    mTransationPending = false;
735cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mTransactionCV.broadcast();
736edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
737edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
738edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handlePageFlip()
739edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
74099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    const DisplayHardware& hw = graphicPlane(0).displayHardware();
74199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    const Region screenRegion(hw.bounds());
74299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
7431bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian    const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
74499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    const bool visibleRegions = lockPageFlip(currentLayers);
745edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
74699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        if (visibleRegions || mVisibleRegionsDirty) {
747edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            Region opaqueRegion;
748edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            computeVisibleRegions(currentLayers, mDirtyRegion, opaqueRegion);
7494da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
7504da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            /*
7514da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian             *  rebuild the visible layer list
7524da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian             */
7531bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian            const size_t count = currentLayers.size();
7544da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            mVisibleLayersSortedByZ.clear();
7554da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            mVisibleLayersSortedByZ.setCapacity(count);
7564da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            for (size_t i=0 ; i<count ; i++) {
7574da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian                if (!currentLayers[i]->visibleRegionScreen.isEmpty())
7584da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian                    mVisibleLayersSortedByZ.add(currentLayers[i]);
7594da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            }
7604da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
761edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mWormholeRegion = screenRegion.subtract(opaqueRegion);
762edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = false;
763ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian            invalidateHwcGeometry();
764edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
765edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
766edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    unlockPageFlip(currentLayers);
7670dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian
7680dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    mDirtyRegion.orSelf(getAndClearInvalidateRegion());
769edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDirtyRegion.andSelf(screenRegion);
770edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
771edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
772ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopianvoid SurfaceFlinger::invalidateHwcGeometry()
773ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian{
774ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian    mHwWorkListDirty = true;
775ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian}
776ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian
777edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool SurfaceFlinger::lockPageFlip(const LayerVector& currentLayers)
778edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
779edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    bool recomputeVisibleRegions = false;
780edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t count = currentLayers.size();
781076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBase> const* layers = currentLayers.array();
782edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (size_t i=0 ; i<count ; i++) {
783b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
784edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->lockPageFlip(recomputeVisibleRegions);
785edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
786edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return recomputeVisibleRegions;
787edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
788edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
789edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::unlockPageFlip(const LayerVector& currentLayers)
790edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
791edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(graphicPlane(0));
792edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Transform& planeTransform(plane.transform());
79399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    const size_t count = currentLayers.size();
794076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBase> const* layers = currentLayers.array();
795edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (size_t i=0 ; i<count ; i++) {
796b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
797edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->unlockPageFlip(planeTransform, mDirtyRegion);
798edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
799edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
800edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
80199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::handleRefresh()
80299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
80399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    bool needInvalidate = false;
80499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
80599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    const size_t count = currentLayers.size();
80699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
80799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
80899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        if (layer->onPreComposition()) {
80999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            needInvalidate = true;
81099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        }
81199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    }
81299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    if (needInvalidate) {
81399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        signalLayerUpdate();
81499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    }
81599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
81699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
81799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
818a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopianvoid SurfaceFlinger::handleWorkList()
819a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian{
820a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    mHwWorkListDirty = false;
821a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    HWComposer& hwc(graphicPlane(0).displayHardware().getHwComposer());
822a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    if (hwc.initCheck() == NO_ERROR) {
823a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        const Vector< sp<LayerBase> >& currentLayers(mVisibleLayersSortedByZ);
824a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        const size_t count = currentLayers.size();
825a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        hwc.createWorkList(count);
82645721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        hwc_layer_t* const cur(hwc.getLayers());
82745721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        for (size_t i=0 ; cur && i<count ; i++) {
82845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            currentLayers[i]->setGeometry(&cur[i]);
82953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian            if (mDebugDisableHWC || mDebugRegion) {
83073d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian                cur[i].compositionType = HWC_FRAMEBUFFER;
83173d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian                cur[i].flags |= HWC_SKIP_LAYER;
83273d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian            }
833a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        }
834a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
835a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian}
836b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian
837edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleRepaint()
838edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
839b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // compute the invalid region
8400656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian    mSwapRegion.orSelf(mDirtyRegion);
841edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
84299ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten    if (CC_UNLIKELY(mDebugRegion)) {
843edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        debugFlashRegions();
844edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
845edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
846b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // set the frame buffer
847b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
848b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    glMatrixMode(GL_MODELVIEW);
849b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    glLoadIdentity();
850edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
851edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t flags = hw.getFlags();
8528b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber    if ((flags & DisplayHardware::SWAP_RECTANGLE) ||
8538b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber        (flags & DisplayHardware::BUFFER_PRESERVED))
854df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian    {
85529d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // we can redraw only what's dirty, but since SWAP_RECTANGLE only
85629d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // takes a rectangle, we must make sure to update that whole
85729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // rectangle in that case
85829d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        if (flags & DisplayHardware::SWAP_RECTANGLE) {
859b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            // TODO: we really should be able to pass a region to
86029d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // SWAP_RECTANGLE so that we don't have to redraw all this.
8610656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian            mDirtyRegion.set(mSwapRegion.bounds());
86229d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        } else {
86329d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // in the BUFFER_PRESERVED case, obviously, we can update only
86429d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // what's needed and nothing more.
86529d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // NOTE: this is NOT a common case, as preserving the backbuffer
86629d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // is costly and usually involves copying the whole update back.
86729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        }
868edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
86995a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian        if (flags & DisplayHardware::PARTIAL_UPDATES) {
87029d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // We need to redraw the rectangle that will be updated
871df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian            // (pushed to the framebuffer).
87295a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian            // This is needed because PARTIAL_UPDATES only takes one
87329d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // rectangle instead of a region (see DisplayHardware::flip())
8740656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian            mDirtyRegion.set(mSwapRegion.bounds());
875edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
87629d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // we need to redraw everything (the whole screen)
877edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mDirtyRegion.set(hw.bounds());
8780656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian            mSwapRegion = mDirtyRegion;
879edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
880edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
881edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
8829c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    setupHardwareComposer(mDirtyRegion);
883edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    composeSurfaces(mDirtyRegion);
884edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
8859c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    // update the swap region and clear the dirty region
8869c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    mSwapRegion.orSelf(mDirtyRegion);
887edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDirtyRegion.clear();
888edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
889edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
8909c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopianvoid SurfaceFlinger::setupHardwareComposer(Region& dirtyInOut)
891edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
892f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
893f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    HWComposer& hwc(hw.getHwComposer());
894f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    hwc_layer_t* const cur(hwc.getLayers());
895f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    if (!cur) {
8969c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        return;
897edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
898a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
8994da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian    const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
90045721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    size_t count = layers.size();
901a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
902e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block    ALOGE_IF(hwc.getNumLayers() != count,
90345721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            "HAL number of layers (%d) doesn't match surfaceflinger (%d)",
90445721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            hwc.getNumLayers(), count);
905a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
90645721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    // just to be extra-safe, use the smallest count
90724925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling    if (hwc.initCheck() == NO_ERROR) {
90824925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling        count = count < hwc.getNumLayers() ? count : hwc.getNumLayers();
90924925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling    }
910a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
91145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    /*
91245721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     *  update the per-frame h/w composer data for each layer
91345721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     *  and build the transparent region of the FB
91445721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     */
915f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
916f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
917f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        layer->setPerFrameData(&cur[i]);
918f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    }
9199c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    const size_t fbLayerCount = hwc.getLayerCount(HWC_FRAMEBUFFER);
920f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    status_t err = hwc.prepare();
921e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block    ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
922f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian
923f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    if (err == NO_ERROR) {
9249c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // what's happening here is tricky.
9259c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // we want to clear all the layers with the CLEAR_FB flags
9269c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // that are opaque.
9279c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // however, since some GPU are efficient at preserving
9289c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // the backbuffer, we want to take advantage of that so we do the
9299c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // clear only in the dirty region (other areas will be preserved
9309c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // on those GPUs).
9319c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        //   NOTE: on non backbuffer preserving GPU, the dirty region
9329c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        //   has already been expanded as needed, so the code is correct
9339c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        //   there too.
9349c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        //
9359c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // However, the content of the framebuffer cannot be trusted when
9369c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // we switch to/from FB/OVERLAY, in which case we need to
9379c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // expand the dirty region to those areas too.
9389c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        //
9399c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // Note also that there is a special case when switching from
9409c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // "no layers in FB" to "some layers in FB", where we need to redraw
9419c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // the entire FB, since some areas might contain uninitialized
9429c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // data.
9439c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        //
9449c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // Also we want to make sure to not clear areas that belong to
9453a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian        // layers above that won't redraw (we would just be erasing them),
9469c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // that is, we can't erase anything outside the dirty region.
947a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
9489c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        Region transparent;
949f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian
9509c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        if (!fbLayerCount && hwc.getLayerCount(HWC_FRAMEBUFFER)) {
9519c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian            transparent.set(hw.getBounds());
9529c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian            dirtyInOut = transparent;
9539c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        } else {
9549c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian            for (size_t i=0 ; i<count ; i++) {
9559c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                const sp<LayerBase>& layer(layers[i]);
9569c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                if ((cur[i].hints & HWC_HINT_CLEAR_FB) && layer->isOpaque()) {
9579c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                    transparent.orSelf(layer->visibleRegionScreen);
9589c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                }
9599c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                bool isOverlay = (cur[i].compositionType != HWC_FRAMEBUFFER);
9609c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                if (isOverlay != layer->isOverlay()) {
9619c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                    // we transitioned to/from overlay, so add this layer
9629c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                    // to the dirty region so the framebuffer can be either
9639c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                    // cleared or redrawn.
9649c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                    dirtyInOut.orSelf(layer->visibleRegionScreen);
9659c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                }
9669c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                layer->setOverlay(isOverlay);
967f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian            }
9689c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian            // don't erase stuff outside the dirty region
9699c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian            transparent.andSelf(dirtyInOut);
970f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        }
971f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian
972f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        /*
973f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian         *  clear the area of the FB that need to be transparent
974f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian         */
975f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        if (!transparent.isEmpty()) {
976f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian            glClearColor(0,0,0,0);
977f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian            Region::const_iterator it = transparent.begin();
978f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian            Region::const_iterator const end = transparent.end();
979f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian            const int32_t height = hw.getHeight();
980f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian            while (it != end) {
981f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian                const Rect& r(*it++);
982f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian                const GLint sy = height - (r.top + r.height());
983f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian                glScissor(r.left, sy, r.width(), r.height());
984f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian                glClear(GL_COLOR_BUFFER_BIT);
985f20a32415d055336bc6016fa2de36d126db32746Mathias Agopian            }
986a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        }
987a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
988f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian}
989f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian
990f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopianvoid SurfaceFlinger::composeSurfaces(const Region& dirty)
991f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian{
992cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
993cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian    HWComposer& hwc(hw.getHwComposer());
994cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian
995cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian    const size_t fbLayerCount = hwc.getLayerCount(HWC_FRAMEBUFFER);
99699ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten    if (CC_UNLIKELY(fbLayerCount && !mWormholeRegion.isEmpty())) {
997f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        // should never happen unless the window manager has a bug
998f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        // draw something...
999f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        drawWormhole();
1000f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    }
100145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian
100245721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    /*
100345721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     * and then, render the layers targeted at the framebuffer
100445721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     */
1005cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian    hwc_layer_t* const cur(hwc.getLayers());
1006f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
1007f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    size_t count = layers.size();
100845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
10099c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        if (cur && (cur[i].compositionType != HWC_FRAMEBUFFER)) {
1010f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian            continue;
101145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        }
101245721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
101345721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        const Region clip(dirty.intersect(layer->visibleRegionScreen));
101445721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        if (!clip.isEmpty()) {
101545721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            layer->draw(clip);
101645721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        }
101745721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    }
1018edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1019edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1020edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::debugFlashRegions()
1021edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
10220a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
10230a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    const uint32_t flags = hw.getFlags();
102453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian    const int32_t height = hw.getHeight();
10250656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian    if (mSwapRegion.isEmpty()) {
102653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian        return;
102753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian    }
10280a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
10290a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    if (!((flags & DisplayHardware::SWAP_RECTANGLE) ||
10300a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian            (flags & DisplayHardware::BUFFER_PRESERVED))) {
10310a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        const Region repaint((flags & DisplayHardware::PARTIAL_UPDATES) ?
10320a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian                mDirtyRegion.bounds() : hw.bounds());
10330a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        composeSurfaces(repaint);
10340a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    }
10350a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
1036c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_EXTERNAL_OES);
1037c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_2D);
1038edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_BLEND);
1039edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_SCISSOR_TEST);
1040edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
10410926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    static int toggle = 0;
10420926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    toggle = 1 - toggle;
10430926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    if (toggle) {
10440a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        glColor4f(1, 0, 1, 1);
10450926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    } else {
10460a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        glColor4f(1, 1, 0, 1);
10470926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    }
1048edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
104920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    Region::const_iterator it = mDirtyRegion.begin();
105020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    Region::const_iterator const end = mDirtyRegion.end();
105120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    while (it != end) {
105220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        const Rect& r = *it++;
1053edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLfloat vertices[][2] = {
105453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.left,  height - r.top },
105553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.left,  height - r.bottom },
105653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.right, height - r.bottom },
105753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.right, height - r.top }
1058edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        };
1059edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glVertexPointer(2, GL_FLOAT, 0, vertices);
1060edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1061edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
10620a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
10630656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian    hw.flip(mSwapRegion);
1064edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1065edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mDebugRegion > 1)
10660a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        usleep(mDebugRegion * 1000);
1067edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1068edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glEnable(GL_SCISSOR_TEST);
1069edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1070edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1071edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::drawWormhole() const
1072edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1073edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Region region(mWormholeRegion.intersect(mDirtyRegion));
1074edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (region.isEmpty())
1075edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1076edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1077edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw(graphicPlane(0).displayHardware());
1078edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int32_t width = hw.getWidth();
1079edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int32_t height = hw.getHeight();
1080edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
108199ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten    if (CC_LIKELY(!mDebugBackground)) {
10820a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        glClearColor(0,0,0,0);
108320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        Region::const_iterator it = region.begin();
108420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        Region::const_iterator const end = region.end();
108520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        while (it != end) {
108620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            const Rect& r = *it++;
1087edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const GLint sy = height - (r.top + r.height());
1088edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glScissor(r.left, sy, r.width(), r.height());
1089edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glClear(GL_COLOR_BUFFER_BIT);
1090edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1091edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
1092edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GLshort vertices[][2] = { { 0, 0 }, { width, 0 },
1093edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                { width, height }, { 0, height }  };
1094edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GLshort tcoords[][2] = { { 0, 0 }, { 1, 0 },  { 1, 1 }, { 0, 1 } };
1095c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian
1096edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glVertexPointer(2, GL_SHORT, 0, vertices);
1097edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glTexCoordPointer(2, GL_SHORT, 0, tcoords);
1098edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
1099c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian
1100c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian        glDisable(GL_TEXTURE_EXTERNAL_OES);
1101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glEnable(GL_TEXTURE_2D);
1102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glBindTexture(GL_TEXTURE_2D, mWormholeTexName);
1103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glMatrixMode(GL_TEXTURE);
1105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glLoadIdentity();
1106c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian
1107c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian        glDisable(GL_BLEND);
1108c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian
1109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glScalef(width*(1.0f/32.0f), height*(1.0f/32.0f), 1);
111020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        Region::const_iterator it = region.begin();
111120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        Region::const_iterator const end = region.end();
111220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        while (it != end) {
111320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            const Rect& r = *it++;
1114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const GLint sy = height - (r.top + r.height());
1115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glScissor(r.left, sy, r.width(), r.height());
1116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1119a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        glDisable(GL_TEXTURE_2D);
1120ebeb7095961e09f5cff0c7cf2c04fa4770b2e033Mathias Agopian        glLoadIdentity();
1121ebeb7095961e09f5cff0c7cf2c04fa4770b2e033Mathias Agopian        glMatrixMode(GL_MODELVIEW);
1122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1125076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::addLayer(const sp<LayerBase>& layer)
1126edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1127edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
1128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    addLayer_l(layer);
1129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
1130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1133076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::addLayer_l(const sp<LayerBase>& layer)
1134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1135f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian    ssize_t i = mCurrentState.layersSortedByZ.add(layer);
11361b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    return (i < 0) ? status_t(i) : status_t(NO_ERROR);
11371b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian}
11381b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
113996f0819f81293076e652792794a961543e6750d7Mathias Agopianssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
114096f0819f81293076e652792794a961543e6750d7Mathias Agopian        const sp<LayerBaseClient>& lbc)
11411b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
114296f0819f81293076e652792794a961543e6750d7Mathias Agopian    // attach this layer to the client
11434f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    size_t name = client->attachLayer(lbc);
11444f113740180b6512b43723c4728f262882dc9b45Mathias Agopian
11454f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    Mutex::Autolock _l(mStateLock);
114696f0819f81293076e652792794a961543e6750d7Mathias Agopian
114796f0819f81293076e652792794a961543e6750d7Mathias Agopian    // add this layer to the current state list
114896f0819f81293076e652792794a961543e6750d7Mathias Agopian    addLayer_l(lbc);
114996f0819f81293076e652792794a961543e6750d7Mathias Agopian
11504f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    return ssize_t(name);
115196f0819f81293076e652792794a961543e6750d7Mathias Agopian}
115296f0819f81293076e652792794a961543e6750d7Mathias Agopian
115396f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer)
115496f0819f81293076e652792794a961543e6750d7Mathias Agopian{
115596f0819f81293076e652792794a961543e6750d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
115696f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = purgatorizeLayer_l(layer);
115796f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR)
115896f0819f81293076e652792794a961543e6750d7Mathias Agopian        setTransactionFlags(eTransactionNeeded);
115996f0819f81293076e652792794a961543e6750d7Mathias Agopian    return err;
1160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1162076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase)
1163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1164b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<LayerBaseClient> lbc(layerBase->getLayerBaseClient());
1165b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (lbc != 0) {
11660d1561275e80073807ac04728951782d943f8882Mathias Agopian        mLayerMap.removeItem( lbc->getSurfaceBinder() );
1167b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    }
1168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase);
1169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (index >= 0) {
1170076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved = true;
1171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
1172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
11733d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    return status_t(index);
1174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
11769a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase)
11779a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
117876cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    // First add the layer to the purgatory list, which makes sure it won't
117976cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    // go away, then remove it from the main list (through a transaction).
11809a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    ssize_t err = removeLayer_l(layerBase);
118176cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    if (err >= 0) {
118276cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian        mLayerPurgatory.add(layerBase);
118376cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    }
11848c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian
11852f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall    mLayersPendingRemoval.push(layerBase);
11860b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian
11873d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // it's possible that we don't find a layer, because it might
11883d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // have been destroyed already -- this is not technically an error
118996f0819f81293076e652792794a961543e6750d7Mathias Agopian    // from the user because there is a race between Client::destroySurface(),
119096f0819f81293076e652792794a961543e6750d7Mathias Agopian    // ~Client() and ~ISurface().
11919a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err;
11929a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
11939a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
119496f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::invalidateLayerVisibility(const sp<LayerBase>& layer)
1195edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
119696f0819f81293076e652792794a961543e6750d7Mathias Agopian    layer->forceVisibilityTransaction();
119796f0819f81293076e652792794a961543e6750d7Mathias Agopian    setTransactionFlags(eTraversalNeeded);
119896f0819f81293076e652792794a961543e6750d7Mathias Agopian    return NO_ERROR;
1199edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1200edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1201dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopianuint32_t SurfaceFlinger::peekTransactionFlags(uint32_t flags)
1202dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian{
1203dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian    return android_atomic_release_load(&mTransactionFlags);
1204dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian}
1205dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian
1206edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags)
1207edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return android_atomic_and(~flags, &mTransactionFlags) & flags;
1209edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1210edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1211bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags)
1212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t old = android_atomic_or(flags, &mTransactionFlags);
1214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((old & flags)==0) { // wake the server up
121599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        signalTransaction();
1216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1217edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return old;
1218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1221b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennisvoid SurfaceFlinger::setTransactionState(const Vector<ComposerState>& state,
122228378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        int orientation, uint32_t flags) {
1223698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
1224cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
122528378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    uint32_t transactionFlags = 0;
1226b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis    if (mCurrentState.orientation != orientation) {
1227b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis        if (uint32_t(orientation)<=eOrientation270 || orientation==42) {
1228b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis            mCurrentState.orientation = orientation;
122928378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis            transactionFlags |= eTransactionNeeded;
1230b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis        } else if (orientation != eOrientationUnchanged) {
123132397c1cd3327905173b36baa6fd1c579bc328ffSteve Block            ALOGW("setTransactionState: ignoring unrecognized orientation: %d",
1232b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis                    orientation);
1233b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis        }
1234b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis    }
1235b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis
1236698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    const size_t count = state.size();
1237698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
1238698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const ComposerState& s(state[i]);
1239698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        sp<Client> client( static_cast<Client *>(s.client.get()) );
124028378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        transactionFlags |= setClientStateLocked(client, s.state);
1241698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    }
1242386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian
124328378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    if (transactionFlags) {
1244386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // this triggers the transaction
124528378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        setTransactionFlags(transactionFlags);
1246698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian
1247386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // if this is a synchronous transaction, wait for it to take effect
1248386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // before returning.
1249386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        if (flags & eSynchronous) {
1250386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            mTransationPending = true;
1251386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        }
1252386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        while (mTransationPending) {
1253386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
1254386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            if (CC_UNLIKELY(err != NO_ERROR)) {
1255386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                // just in case something goes wrong in SF, return to the
1256386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                // called after a few seconds.
125732397c1cd3327905173b36baa6fd1c579bc328ffSteve Block                ALOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!");
1258386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                mTransationPending = false;
1259386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                break;
1260386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            }
1261cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        }
1262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
12650ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopiansp<ISurface> SurfaceFlinger::createSurface(
12660ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        ISurfaceComposerClient::surface_data_t* params,
12670ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const String8& name,
12680ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const sp<Client>& client,
1269edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        DisplayID d, uint32_t w, uint32_t h, PixelFormat format,
1270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t flags)
1271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1272076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBaseClient> layer;
1273a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    sp<ISurface> surfaceHandle;
12746e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian
12756e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    if (int32_t(w|h) < 0) {
1276e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE("createSurface() failed, w or h is negative (w=%d, h=%d)",
12776e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian                int(w), int(h));
12786e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian        return surfaceHandle;
12796e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    }
12808b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
12819d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block    //ALOGD("createSurface for pid %d (%d x %d)", pid, w, h);
1282b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<Layer> normalLayer;
1283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (flags & eFXSurfaceMask) {
1284edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceNormal:
1285a5529c8778c2f407f482fc12165aeb76c0f505c2Mathias Agopian            normalLayer = createNormalSurface(client, d, w, h, flags, format);
1286a5529c8778c2f407f482fc12165aeb76c0f505c2Mathias Agopian            layer = normalLayer;
1287edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
1288edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceBlur:
12891293a8eb567fd63c072a6970fa9dcf37d076059fMathias Agopian            // for now we treat Blur as Dim, until we can implement it
12901293a8eb567fd63c072a6970fa9dcf37d076059fMathias Agopian            // efficiently.
1291edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceDim:
129296f0819f81293076e652792794a961543e6750d7Mathias Agopian            layer = createDimSurface(client, d, w, h, flags);
1293edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
1294118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        case eFXSurfaceScreenshot:
1295118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian            layer = createScreenshotSurface(client, d, w, h, flags);
1296118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian            break;
1297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1299076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (layer != 0) {
130096f0819f81293076e652792794a961543e6750d7Mathias Agopian        layer->initStates(w, h, flags);
1301285dbde2e0cd0057be070ded3be8f5f453147edcMathias Agopian        layer->setName(name);
130296f0819f81293076e652792794a961543e6750d7Mathias Agopian        ssize_t token = addClientLayer(client, layer);
1303b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        surfaceHandle = layer->getSurface();
13058b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber        if (surfaceHandle != 0) {
130696f0819f81293076e652792794a961543e6750d7Mathias Agopian            params->token = token;
1307a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            params->identity = layer->getIdentity();
1308b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            if (normalLayer != 0) {
1309b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian                Mutex::Autolock _l(mStateLock);
1310a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                mLayerMap.add(layer->getSurfaceBinder(), normalLayer);
1311b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            }
13121c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        }
1313b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
131496f0819f81293076e652792794a961543e6750d7Mathias Agopian        setTransactionFlags(eTransactionNeeded);
1315edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return surfaceHandle;
1318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1320b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<Layer> SurfaceFlinger::createNormalSurface(
1321f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        const sp<Client>& client, DisplayID display,
132296f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags,
13231c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        PixelFormat& format)
1324edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1325edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize the surfaces
1326edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (format) { // TODO: take h/w into account
1327edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSPARENT:
1328edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSLUCENT:
1329edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        format = PIXEL_FORMAT_RGBA_8888;
1330edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1331edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_OPAQUE:
1332a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888
1333a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian        format = PIXEL_FORMAT_RGB_565;
1334a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#else
13358f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian        format = PIXEL_FORMAT_RGBX_8888;
1336a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif
1337edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1338edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1339edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1340a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888
1341a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian    if (format == PIXEL_FORMAT_RGBX_8888)
1342a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian        format = PIXEL_FORMAT_RGBA_8888;
1343a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif
1344a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian
134596f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<Layer> layer = new Layer(this, display, client);
1346f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian    status_t err = layer->setBuffers(w, h, format, flags);
134799ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten    if (CC_LIKELY(err != NO_ERROR)) {
1348e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE("createNormalSurfaceLocked() failed (%s)", strerror(-err));
1349076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        layer.clear();
1350edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1351edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1352edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1353edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1354b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<LayerDim> SurfaceFlinger::createDimSurface(
1355f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        const sp<Client>& client, DisplayID display,
135696f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags)
1357edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
135896f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<LayerDim> layer = new LayerDim(this, display, client);
1359118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    return layer;
1360118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
1361118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
1362118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopiansp<LayerScreenshot> SurfaceFlinger::createScreenshotSurface(
1363118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        const sp<Client>& client, DisplayID display,
1364118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags)
1365118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{
1366118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    sp<LayerScreenshot> layer = new LayerScreenshot(this, display, client);
1367edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1368edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1369edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
137096f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeSurface(const sp<Client>& client, SurfaceID sid)
13719a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
13729a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    /*
13739a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     * called by the window manager, when a surface should be marked for
13749a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     * destruction.
13758b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber     *
13760aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * The surface is removed from the current and drawing lists, but placed
13770aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * in the purgatory queue, so it's not destroyed right-away (we need
13780aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * to wait for all client's references to go away first).
13799a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     */
13809a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
138148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    status_t err = NAME_NOT_FOUND;
13820aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian    Mutex::Autolock _l(mStateLock);
138396f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<LayerBaseClient> layer = client->getLayerUser(sid);
138448d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    if (layer != 0) {
138548d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        err = purgatorizeLayer_l(layer);
138648d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        if (err == NO_ERROR) {
138748d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian            setTransactionFlags(eTransactionNeeded);
138848d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        }
13899a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    }
13909a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return err;
13919a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
13929a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
1393ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopianstatus_t SurfaceFlinger::destroySurface(const wp<LayerBaseClient>& layer)
1394edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1395759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian    // called by ~ISurface() when all references are gone
1396ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    status_t err = NO_ERROR;
1397ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    sp<LayerBaseClient> l(layer.promote());
1398ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    if (l != NULL) {
1399ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        Mutex::Autolock _l(mStateLock);
1400ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        err = removeLayer_l(l);
1401ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        if (err == NAME_NOT_FOUND) {
1402ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // The surface wasn't in the current list, which means it was
1403ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // removed already, which means it is in the purgatory,
1404ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // and need to be removed from there.
1405ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            ssize_t idx = mLayerPurgatory.remove(l);
1406e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block            ALOGE_IF(idx < 0,
1407ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian                    "layer=%p is not in the purgatory list", l.get());
1408f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        }
1409e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE_IF(err<0 && err != NAME_NOT_FOUND,
1410ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian                "error removing layer=%p (%s)", l.get(), strerror(-err));
1411ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    }
1412ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    return err;
1413edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1414edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1415698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopianuint32_t SurfaceFlinger::setClientStateLocked(
141696f0819f81293076e652792794a961543e6750d7Mathias Agopian        const sp<Client>& client,
1417698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const layer_state_t& s)
1418edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1419edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t flags = 0;
1420698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    sp<LayerBaseClient> layer(client->getLayerUser(s.surface));
1421698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    if (layer != 0) {
1422698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const uint32_t what = s.what;
1423698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & ePositionChanged) {
1424698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setPosition(s.x, s.y))
1425698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1426698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1427698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eLayerChanged) {
1428698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
1429698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setLayer(s.z)) {
1430698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                mCurrentState.layersSortedByZ.removeAt(idx);
1431698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                mCurrentState.layersSortedByZ.add(layer);
1432698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                // we need traversal (state changed)
1433698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                // AND transaction (list changed)
1434698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTransactionNeeded|eTraversalNeeded;
1435edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1436698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1437698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eSizeChanged) {
1438698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setSize(s.w, s.h)) {
1439698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1440edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1441edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1442698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eAlphaChanged) {
1443698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f)))
1444698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1445698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1446698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eMatrixChanged) {
1447698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setMatrix(s.matrix))
1448698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1449698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1450698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eTransparentRegionChanged) {
1451698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setTransparentRegionHint(s.transparentRegion))
1452698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1453698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1454698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eVisibilityChanged) {
1455698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setFlags(s.flags, s.mask))
1456698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1457698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1458edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1459698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    return flags;
1460edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1461edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1462edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::screenReleased(int dpy)
1463edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1464edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // this may be called by a signal handler, we can't do too much in here
1465edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    android_atomic_or(eConsoleReleased, &mConsoleSignals);
146699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    signalTransaction();
1467edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1468edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1469edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::screenAcquired(int dpy)
1470edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1471edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // this may be called by a signal handler, we can't do too much in here
1472edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    android_atomic_or(eConsoleAcquired, &mConsoleSignals);
147399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    signalTransaction();
1474edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1475edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1476edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
1477edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
14781d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling    const size_t SIZE = 4096;
1479edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char buffer[SIZE];
1480edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    String8 result;
148199b49840d309727678b77403d6cc9f920111623fMathias Agopian
148299b49840d309727678b77403d6cc9f920111623fMathias Agopian    if (!PermissionCache::checkCallingPermission(sDump)) {
1483edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        snprintf(buffer, SIZE, "Permission Denial: "
1484edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                "can't dump SurfaceFlinger from pid=%d, uid=%d\n",
1485edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                IPCThreadState::self()->getCallingPid(),
1486edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                IPCThreadState::self()->getCallingUid());
1487edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        result.append(buffer);
1488edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
14899795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // Try to get the main lock, but don't insist if we can't
14909795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // (this would indicate SF is stuck, but we want to be able to
14919795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // print something in dumpsys).
14929795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        int retry = 3;
14939795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        while (mStateLock.tryLock()<0 && --retry>=0) {
14949795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            usleep(1000000);
14959795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
14969795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const bool locked(retry >= 0);
14979795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (!locked) {
14988b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber            snprintf(buffer, SIZE,
14999795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "SurfaceFlinger appears to be unresponsive, "
15009795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "dumping anyways (no locks held)\n");
15019795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            result.append(buffer);
15029795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
15039795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
150482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        bool dumpAll = true;
150582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        size_t index = 0;
150625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        size_t numArgs = args.size();
150725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        if (numArgs) {
150882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            dumpAll = false;
150925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
151025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
151125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--list"))) {
151225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                index++;
151325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                listLayersLocked(args, index, result, buffer, SIZE);
151425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            }
151525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
151625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
151725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--latency"))) {
151882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                index++;
151982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                dumpStatsLocked(args, index, result, buffer, SIZE);
152082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            }
152125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
152225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
152325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--latency-clear"))) {
152425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                index++;
152525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                clearStatsLocked(args, index, result, buffer, SIZE);
152625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            }
1527edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
15281b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
152982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (dumpAll) {
153082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            dumpAllLocked(result, buffer, SIZE);
153182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
153248b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
153382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (locked) {
153482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mStateLock.unlock();
153548b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        }
153682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
153782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    write(fd, result.string(), result.size());
153882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    return NO_ERROR;
153982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
154048b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
154125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::listLayersLocked(const Vector<String16>& args, size_t& index,
154225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        String8& result, char* buffer, size_t SIZE) const
154325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
154425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
154525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const size_t count = currentLayers.size();
154625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
154725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
154825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        snprintf(buffer, SIZE, "%s\n", layer->getName().string());
154925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        result.append(buffer);
155025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
155125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
155225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
155382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index,
155482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        String8& result, char* buffer, size_t SIZE) const
155582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
155682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    String8 name;
155782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    if (index < args.size()) {
155882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        name = String8(args[index]);
155982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        index++;
156082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
156148b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
156282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
156382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const size_t count = currentLayers.size();
156482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    for (size_t i=0 ; i<count ; i++) {
156582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
156682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (name.isEmpty()) {
156782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            snprintf(buffer, SIZE, "%s\n", layer->getName().string());
156882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            result.append(buffer);
156982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
157082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (name.isEmpty() || (name == layer->getName())) {
157182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            layer->dumpStats(result, buffer, SIZE);
157282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
157382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
157482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
1575ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian
157625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& index,
157725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        String8& result, char* buffer, size_t SIZE) const
157825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
157925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    String8 name;
158025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    if (index < args.size()) {
158125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        name = String8(args[index]);
158225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        index++;
158325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
158425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
158525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
158625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const size_t count = currentLayers.size();
158725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
158825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
158925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        if (name.isEmpty() || (name == layer->getName())) {
159025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            layer->clearStats();
159125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        }
159225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
159325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
159425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
159582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpAllLocked(
159682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        String8& result, char* buffer, size_t SIZE) const
159782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
159882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    // figure out if we're stuck somewhere
159982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t now = systemTime();
160082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t inSwapBuffers(mDebugInSwapBuffers);
160182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t inTransaction(mDebugInTransaction);
160282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0;
160382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0;
1604bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
160582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
160682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump the visible layer list
160782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
160882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
160982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const size_t count = currentLayers.size();
161082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "Visible layers (count = %d)\n", count);
161182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
161282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    for (size_t i=0 ; i<count ; i++) {
161382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
161482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        layer->dump(result, buffer, SIZE);
161582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
1616bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
161782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
161882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump the layers in the purgatory
161982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
1620ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian
162182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const size_t purgatorySize = mLayerPurgatory.size();
162282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "Purgatory state (%d entries)\n", purgatorySize);
162382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
162482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    for (size_t i=0 ; i<purgatorySize ; i++) {
162582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
162682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        layer->shortDump(result, buffer, SIZE);
162782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
16281b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
162982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
163082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump SurfaceFlinger global state
163182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
16321b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
163382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "SurfaceFlinger global state:\n");
163482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
16351b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
163682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const GLExtensions& extensions(GLExtensions::getInstance());
163782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "GLES: %s, %s, %s\n",
163882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            extensions.getVendor(),
163982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            extensions.getRenderer(),
164082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            extensions.getVersion());
164182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
1642d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
164382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "EGL : %s\n",
164482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            eglQueryString(graphicPlane(0).getEGLDisplay(),
164582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                    EGL_VERSION_HW_ANDROID));
164682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
164773d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian
164882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "EXTS: %s\n", extensions.getExtension());
164982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
16509795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
165182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    mWormholeRegion.dump(result, "WormholeRegion");
165282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
165382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE,
165482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  orientation=%d, canDraw=%d\n",
165582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mCurrentState.orientation, hw.canDraw());
165682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
165782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE,
165882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  last eglSwapBuffers() time: %f us\n"
165982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  last transaction time     : %f us\n"
1660c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian            "  transaction-flags         : %08x\n"
166182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  refresh-rate              : %f fps\n"
166282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  x-dpi                     : %f\n"
166382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  y-dpi                     : %f\n",
166482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mLastSwapBufferTime/1000.0,
166582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mLastTransactionTime/1000.0,
1666c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian            mTransactionFlags,
166782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            hw.getRefreshRate(),
166882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            hw.getDpiX(),
166982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            hw.getDpiY());
167082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
167182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
167282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "  eglSwapBuffers time: %f us\n",
167382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            inSwapBuffersDuration/1000.0);
167482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
167582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
167682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "  transaction time: %f us\n",
167782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            inTransactionDuration/1000.0);
167882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
167982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
168082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
168182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * VSYNC state
168282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
168382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    mEventThread->dump(result, buffer, SIZE);
168482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
168582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
168682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump HWComposer state
168782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
168882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    HWComposer& hwc(hw.getHwComposer());
168982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "h/w composer state:\n");
169082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
169182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "  h/w composer %s and %s\n",
169282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            hwc.initCheck()==NO_ERROR ? "present" : "not present",
169382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                    (mDebugDisableHWC || mDebugRegion) ? "disabled" : "enabled");
169482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
169582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    hwc.dump(result, buffer, SIZE, mVisibleLayersSortedByZ);
169682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
169782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
169882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump gralloc state
169982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
170082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
170182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    alloc.dump(result);
170282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    hw.dump(result);
1703edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1704edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1705edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::onTransact(
1706edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
1707edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1708edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (code) {
1709edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case CREATE_CONNECTION:
1710698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        case SET_TRANSACTION_STATE:
1711edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case SET_ORIENTATION:
1712edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case BOOT_FINISHED:
171359119e658a12279e8fff508f8773843de2d90917Mathias Agopian        case TURN_ELECTRON_BEAM_OFF:
17149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        case TURN_ELECTRON_BEAM_ON:
1715edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        {
1716edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // codes that require permission check
1717edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            IPCThreadState* ipc = IPCThreadState::self();
1718edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int pid = ipc->getCallingPid();
1719a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian            const int uid = ipc->getCallingUid();
172099b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
172199b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) {
1722e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block                ALOGE("Permission Denial: "
1723375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                        "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
1724375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                return PERMISSION_DENIED;
1725edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
17261b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
17271b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
17281b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        case CAPTURE_SCREEN:
17291b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
17301b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            // codes that require permission check
17311b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
17321b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int pid = ipc->getCallingPid();
17331b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int uid = ipc->getCallingUid();
173499b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
173599b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) {
1736e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block                ALOGE("Permission Denial: "
17371b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                        "can't read framebuffer pid=%d, uid=%d", pid, uid);
17381b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                return PERMISSION_DENIED;
17391b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            }
17401b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
1741edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1742edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
17431b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
1744edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
1745edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
1746b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        CHECK_INTERFACE(ISurfaceComposer, data, reply);
174799ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten        if (CC_UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) {
1748375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
1749375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int pid = ipc->getCallingPid();
1750375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int uid = ipc->getCallingUid();
1751e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block            ALOGE("Permission Denial: "
1752375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                    "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
1753edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return PERMISSION_DENIED;
1754edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1755edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int n;
1756edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        switch (code) {
175701b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian            case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE
175835b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian            case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE
1759edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1760edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1002:  // SHOW_UPDATES
1761edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                n = data.readInt32();
1762edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDebugRegion = n ? n : (mDebugRegion ? 0 : 1);
176353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
176453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
1765edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1766edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1003:  // SHOW_BACKGROUND
1767edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                n = data.readInt32();
1768edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDebugBackground = n ? 1 : 0;
1769edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1770edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1004:{ // repaint everything
177153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
1772cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
1773cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            }
1774cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            case 1005:{ // force transaction
1775cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
1776cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
1777edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
177853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian            case 1008:  // toggle use of hw composer
177953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                n = data.readInt32();
178053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                mDebugDisableHWC = n ? 1 : 0;
178153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
178253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
178353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                return NO_ERROR;
1784a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian            case 1009:  // toggle use of transform hint
1785a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                n = data.readInt32();
1786a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                mDebugDisableTransformHint = n ? 1 : 0;
1787a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                invalidateHwcGeometry();
1788a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                repaintEverything();
1789a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                return NO_ERROR;
1790edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1010:  // interrogate.
179101b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian                reply->writeInt32(0);
1792edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(0);
1793edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(mDebugRegion);
1794edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(mDebugBackground);
1795edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1796edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1013: {
1797edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                Mutex::Autolock _l(mStateLock);
1798edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                const DisplayHardware& hw(graphicPlane(0).displayHardware());
1799edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(hw.getPageFlipCount());
1800edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1801edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return NO_ERROR;
1802edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1803edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1804edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return err;
1805edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1806edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
180753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopianvoid SurfaceFlinger::repaintEverything() {
180853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
18090dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    const Rect bounds(hw.getBounds());
18100dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    setInvalidateRegion(Region(bounds));
181199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    signalTransaction();
181253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian}
181353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian
18140dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopianvoid SurfaceFlinger::setInvalidateRegion(const Region& reg) {
18150dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    Mutex::Autolock _l(mInvalidateLock);
18160dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    mInvalidateRegion = reg;
18170dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian}
18180dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian
18190dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias AgopianRegion SurfaceFlinger::getAndClearInvalidateRegion() {
18200dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    Mutex::Autolock _l(mInvalidateLock);
18210dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    Region reg(mInvalidateRegion);
18220dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    mInvalidateRegion.clear();
18230dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    return reg;
18240dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian}
18250dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian
182659119e658a12279e8fff508f8773843de2d90917Mathias Agopian// ---------------------------------------------------------------------------
182759119e658a12279e8fff508f8773843de2d90917Mathias Agopian
1828118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopianstatus_t SurfaceFlinger::renderScreenToTexture(DisplayID dpy,
1829118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        GLuint* textureName, GLfloat* uOut, GLfloat* vOut)
1830118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{
1831118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    Mutex::Autolock _l(mStateLock);
1832118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    return renderScreenToTextureLocked(dpy, textureName, uOut, vOut);
1833118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
1834118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
18359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::renderScreenToTextureLocked(DisplayID dpy,
18369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        GLuint* textureName, GLfloat* uOut, GLfloat* vOut)
183759119e658a12279e8fff508f8773843de2d90917Mathias Agopian{
183859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
183959119e658a12279e8fff508f8773843de2d90917Mathias Agopian        return INVALID_OPERATION;
184059119e658a12279e8fff508f8773843de2d90917Mathias Agopian
184159119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // get screen geometry
184259119e658a12279e8fff508f8773843de2d90917Mathias Agopian    const DisplayHardware& hw(graphicPlane(dpy).displayHardware());
184359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    const uint32_t hw_w = hw.getWidth();
184459119e658a12279e8fff508f8773843de2d90917Mathias Agopian    const uint32_t hw_h = hw.getHeight();
184559119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLfloat u = 1;
184659119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLfloat v = 1;
184759119e658a12279e8fff508f8773843de2d90917Mathias Agopian
184859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // make sure to clear all GL error flags
184959119e658a12279e8fff508f8773843de2d90917Mathias Agopian    while ( glGetError() != GL_NO_ERROR ) ;
185059119e658a12279e8fff508f8773843de2d90917Mathias Agopian
185159119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // create a FBO
185259119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLuint name, tname;
185359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glGenTextures(1, &tname);
185459119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
18559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
18569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            hw_w, hw_h, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
185759119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (glGetError() != GL_NO_ERROR) {
1858015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian        while ( glGetError() != GL_NO_ERROR ) ;
185959119e658a12279e8fff508f8773843de2d90917Mathias Agopian        GLint tw = (2 << (31 - clz(hw_w)));
186059119e658a12279e8fff508f8773843de2d90917Mathias Agopian        GLint th = (2 << (31 - clz(hw_h)));
18619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
18629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian                tw, th, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
186359119e658a12279e8fff508f8773843de2d90917Mathias Agopian        u = GLfloat(hw_w) / tw;
186459119e658a12279e8fff508f8773843de2d90917Mathias Agopian        v = GLfloat(hw_h) / th;
186559119e658a12279e8fff508f8773843de2d90917Mathias Agopian    }
186659119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glGenFramebuffersOES(1, &name);
186759119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
18689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES,
18699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0);
187059119e658a12279e8fff508f8773843de2d90917Mathias Agopian
18719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // redraw the screen entirely...
1872c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_EXTERNAL_OES);
1873c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_2D);
187462f7114719d2009dca7dd120f0fe29a24bd77a40Mathias Agopian    glDisable(GL_SCISSOR_TEST);
18759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glClearColor(0,0,0,1);
18769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glClear(GL_COLOR_BUFFER_BIT);
187762f7114719d2009dca7dd120f0fe29a24bd77a40Mathias Agopian    glEnable(GL_SCISSOR_TEST);
1878a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glMatrixMode(GL_MODELVIEW);
1879a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glLoadIdentity();
18809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
18819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const size_t count = layers.size();
18829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (size_t i=0 ; i<count ; ++i) {
18839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
18849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        layer->drawForSreenShot();
18859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
188659119e658a12279e8fff508f8773843de2d90917Mathias Agopian
1887118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    hw.compositionComplete();
1888118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
18899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // back to main framebuffer
18909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
18919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_SCISSOR_TEST);
18929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDeleteFramebuffersOES(1, &name);
189359119e658a12279e8fff508f8773843de2d90917Mathias Agopian
18949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *textureName = tname;
18959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *uOut = u;
18969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *vOut = v;
18979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
18989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
189959119e658a12279e8fff508f8773843de2d90917Mathias Agopian
19009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// ---------------------------------------------------------------------------
190159119e658a12279e8fff508f8773843de2d90917Mathias Agopian
19029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::electronBeamOffAnimationImplLocked()
19039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
19049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // get screen geometry
19059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
19069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_w = hw.getWidth();
19079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_h = hw.getHeight();
1908a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    const Region screenBounds(hw.getBounds());
190959119e658a12279e8fff508f8773843de2d90917Mathias Agopian
19109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat u, v;
19119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLuint tname;
1912118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    status_t result = renderScreenToTextureLocked(0, &tname, &u, &v);
19139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (result != NO_ERROR) {
19149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return result;
19159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
191659119e658a12279e8fff508f8773843de2d90917Mathias Agopian
19179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat vtx[8];
1918a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    const GLfloat texCoords[4][2] = { {0,0}, {0,v}, {u,v}, {u,0} };
19199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
19209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
19219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
19229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
19239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
19249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
19259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glVertexPointer(2, GL_FLOAT, 0, vtx);
19269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
1927ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    /*
1928ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     * Texture coordinate mapping
1929ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *
1930ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *                 u
1931ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *    1 +----------+---+
1932ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |     |    |   |  image is inverted
1933ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |     V    |   |  w.r.t. the texture
1934ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *  1-v +----------+   |  coordinates
1935ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |              |
1936ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |              |
1937ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |              |
1938ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *    0 +--------------+
1939ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      0              1
1940ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *
1941ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     */
1942ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian
19439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class s_curve_interpolator {
19449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float nbFrames, s, v;
19459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
19469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        s_curve_interpolator(int nbFrames, float s)
19479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : nbFrames(1.0f / (nbFrames-1)), s(s),
19489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian          v(1.0f + expf(-s + 0.5f*s)) {
19499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
19509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float operator()(int f) {
19519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const float x = f * nbFrames;
19529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f;
19539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
19549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
19559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class v_stretch {
19579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
19589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
19599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        v_stretch(uint32_t hw_w, uint32_t hw_h)
19609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
19619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
19629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
19639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w + (hw_w * v);
19649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = hw_h - (hw_h * v);
19659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
19669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
1967ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[0] = x;         vtx[1] = y;
1968ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
1969ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
1970ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
19719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
19729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
19739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class h_stretch {
19759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
19769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
19779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        h_stretch(uint32_t hw_w, uint32_t hw_h)
19789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
197959119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
19809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
19819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w - (hw_w * v);
19829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = 1.0f;
19839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
19849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
1985ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[0] = x;         vtx[1] = y;
1986ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
1987ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
1988ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
19899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
19909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
19919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // the full animation is 24 frames
1993ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    char value[PROPERTY_VALUE_MAX];
1994ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    property_get("debug.sf.electron_frames", value, "24");
1995ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    int nbFrames = (atoi(value) + 1) >> 1;
1996ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    if (nbFrames <= 0) // just in case
1997ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian        nbFrames = 24;
1998ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian
19999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itr(nbFrames, 7.5f);
20009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itg(nbFrames, 8.0f);
20019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itb(nbFrames, 8.5f);
20029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    v_stretch vverts(hw_w, hw_h);
2004a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian
2005a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glMatrixMode(GL_TEXTURE);
2006a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glLoadIdentity();
2007a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glMatrixMode(GL_MODELVIEW);
2008a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glLoadIdentity();
2009a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian
20109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnable(GL_BLEND);
20119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBlendFunc(GL_ONE, GL_ONE);
20129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=0 ; i<nbFrames ; i++) {
20139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float x, y, w, h;
20149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vr = itr(i);
20159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vg = itg(i);
20169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vb = itb(i);
20179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // clear screen
20199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(1,1,1,1);
20209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
20219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glEnable(GL_TEXTURE_2D);
202259119e658a12279e8fff508f8773843de2d90917Mathias Agopian
20239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the red plane
20249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vr);
20259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(1,0,0,1);
20269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
20279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the green plane
20299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vg);
20309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,1,0,1);
20319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
20329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the blue plane
20349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vb);
20359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,0,1,1);
20369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
20379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the white highlight (we use the last vertices)
203959119e658a12279e8fff508f8773843de2d90917Mathias Agopian        glDisable(GL_TEXTURE_2D);
204059119e658a12279e8fff508f8773843de2d90917Mathias Agopian        glColorMask(1,1,1,1);
20419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColor4f(vg, vg, vg, 1);
20429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
20439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
20449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
20459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    h_stretch hverts(hw_w, hw_h);
20479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_BLEND);
20489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_TEXTURE_2D);
20499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
20509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=0 ; i<nbFrames ; i++) {
20519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float v = itg(i);
20529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hverts(vtx, v);
20539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
20549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColor4f(1-v, 1-v, 1-v, 1);
20559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
20569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
20579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
20589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
20609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnable(GL_SCISSOR_TEST);
20619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
20629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDeleteTextures(1, &tname);
2063a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    glDisable(GL_TEXTURE_2D);
2064c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_BLEND);
20659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
20669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
20679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::electronBeamOnAnimationImplLocked()
20699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
20709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    status_t result = PERMISSION_DENIED;
20719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
20739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return INVALID_OPERATION;
20749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // get screen geometry
20779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
20789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_w = hw.getWidth();
20799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_h = hw.getHeight();
20809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const Region screenBounds(hw.bounds());
20819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat u, v;
20839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLuint tname;
20849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    result = renderScreenToTextureLocked(0, &tname, &u, &v);
20859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (result != NO_ERROR) {
20869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return result;
20879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
20889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat vtx[8];
20909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const GLfloat texCoords[4][2] = { {0,v}, {0,0}, {u,0}, {u,v} };
20919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
20929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
20939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
20949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
20959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
20969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
20979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glVertexPointer(2, GL_FLOAT, 0, vtx);
20989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class s_curve_interpolator {
21009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float nbFrames, s, v;
21019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
21029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        s_curve_interpolator(int nbFrames, float s)
21039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : nbFrames(1.0f / (nbFrames-1)), s(s),
21049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian          v(1.0f + expf(-s + 0.5f*s)) {
21059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
21069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float operator()(int f) {
21079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const float x = f * nbFrames;
21089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f;
21099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
21109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
21119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class v_stretch {
21139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
21149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
21159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        v_stretch(uint32_t hw_w, uint32_t hw_h)
21169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
211759119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
21189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
21199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w + (hw_w * v);
21209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = hw_h - (hw_h * v);
21219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
21229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
21239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[0] = x;         vtx[1] = y;
21249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
21259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
21269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
21279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
21289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
21299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class h_stretch {
21319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
21329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
21339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        h_stretch(uint32_t hw_w, uint32_t hw_h)
21349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
21359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
21369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
21379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w - (hw_w * v);
21389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = 1.0f;
21399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
21409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
21419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[0] = x;         vtx[1] = y;
21429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
21439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
21449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
21459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
21469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
21479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2148a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian    // the full animation is 12 frames
2149a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian    int nbFrames = 8;
21509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itr(nbFrames, 7.5f);
21519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itg(nbFrames, 8.0f);
21529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itb(nbFrames, 8.5f);
21539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    h_stretch hverts(hw_w, hw_h);
21559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_BLEND);
21569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_TEXTURE_2D);
21579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
21589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=nbFrames-1 ; i>=0 ; i--) {
21599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float v = itg(i);
21609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hverts(vtx, v);
21619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
21629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColor4f(1-v, 1-v, 1-v, 1);
21639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
21649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
21659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
21669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2167a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian    nbFrames = 4;
21689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    v_stretch vverts(hw_w, hw_h);
21699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnable(GL_BLEND);
21709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBlendFunc(GL_ONE, GL_ONE);
21719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=nbFrames-1 ; i>=0 ; i--) {
21729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float x, y, w, h;
21739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vr = itr(i);
21749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vg = itg(i);
21759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vb = itb(i);
217659119e658a12279e8fff508f8773843de2d90917Mathias Agopian
21779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // clear screen
217859119e658a12279e8fff508f8773843de2d90917Mathias Agopian        glColorMask(1,1,1,1);
21799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
21809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glEnable(GL_TEXTURE_2D);
21819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the red plane
21839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vr);
21849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(1,0,0,1);
21859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
21869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the green plane
21889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vg);
21899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,1,0,1);
21909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
21919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the blue plane
21939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vb);
21949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,0,1,1);
21959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
21969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
219859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    }
219959119e658a12279e8fff508f8773843de2d90917Mathias Agopian
22009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
22019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnable(GL_SCISSOR_TEST);
22029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
220359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glDeleteTextures(1, &tname);
2204a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    glDisable(GL_TEXTURE_2D);
2205c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_BLEND);
220659119e658a12279e8fff508f8773843de2d90917Mathias Agopian
22079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
22089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
22099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// ---------------------------------------------------------------------------
22119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2212abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOffImplLocked(int32_t mode)
22139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
22149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    DisplayHardware& hw(graphicPlane(0).editDisplayHardware());
22159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (!hw.canDraw()) {
22169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // we're already off
22179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return NO_ERROR;
22189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
22197ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian
22207ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian    // turn off hwc while we're doing the animation
22217ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian    hw.getHwComposer().disable();
22227ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian    // and make sure to turn it back on (if needed) next time we compose
22237ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian    invalidateHwcGeometry();
22247ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian
2225abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    if (mode & ISurfaceComposer::eElectronBeamAnimationOff) {
2226abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        electronBeamOffAnimationImplLocked();
2227abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    }
2228abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian
2229abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    // always clear the whole screen at the end of the animation
2230abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    glClearColor(0,0,0,1);
2231abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    glDisable(GL_SCISSOR_TEST);
2232abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    glClear(GL_COLOR_BUFFER_BIT);
2233abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    glEnable(GL_SCISSOR_TEST);
2234abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    hw.flip( Region(hw.bounds()) );
2235abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian
2236015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian    return NO_ERROR;
223759119e658a12279e8fff508f8773843de2d90917Mathias Agopian}
223859119e658a12279e8fff508f8773843de2d90917Mathias Agopian
223959119e658a12279e8fff508f8773843de2d90917Mathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOff(int32_t mode)
224059119e658a12279e8fff508f8773843de2d90917Mathias Agopian{
224159119e658a12279e8fff508f8773843de2d90917Mathias Agopian    class MessageTurnElectronBeamOff : public MessageBase {
224259119e658a12279e8fff508f8773843de2d90917Mathias Agopian        SurfaceFlinger* flinger;
2243abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        int32_t mode;
224459119e658a12279e8fff508f8773843de2d90917Mathias Agopian        status_t result;
224559119e658a12279e8fff508f8773843de2d90917Mathias Agopian    public:
2246abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        MessageTurnElectronBeamOff(SurfaceFlinger* flinger, int32_t mode)
2247abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            : flinger(flinger), mode(mode), result(PERMISSION_DENIED) {
224859119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
224959119e658a12279e8fff508f8773843de2d90917Mathias Agopian        status_t getResult() const {
225059119e658a12279e8fff508f8773843de2d90917Mathias Agopian            return result;
225159119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
225259119e658a12279e8fff508f8773843de2d90917Mathias Agopian        virtual bool handler() {
225359119e658a12279e8fff508f8773843de2d90917Mathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
2254abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            result = flinger->turnElectronBeamOffImplLocked(mode);
225559119e658a12279e8fff508f8773843de2d90917Mathias Agopian            return true;
225659119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
225759119e658a12279e8fff508f8773843de2d90917Mathias Agopian    };
225859119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2259abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    sp<MessageBase> msg = new MessageTurnElectronBeamOff(this, mode);
226059119e658a12279e8fff508f8773843de2d90917Mathias Agopian    status_t res = postMessageSync(msg);
226159119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (res == NO_ERROR) {
226259119e658a12279e8fff508f8773843de2d90917Mathias Agopian        res = static_cast<MessageTurnElectronBeamOff*>( msg.get() )->getResult();
22639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // work-around: when the power-manager calls us we activate the
22659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // animation. eventually, the "on" animation will be called
22669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // by the power-manager itself
2267abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        mElectronBeamAnimationMode = mode;
226859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    }
226959119e658a12279e8fff508f8773843de2d90917Mathias Agopian    return res;
227059119e658a12279e8fff508f8773843de2d90917Mathias Agopian}
227159119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
2273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2274abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOnImplLocked(int32_t mode)
22759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
22769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    DisplayHardware& hw(graphicPlane(0).editDisplayHardware());
22779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (hw.canDraw()) {
22789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // we're already on
22799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return NO_ERROR;
22809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
2281abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    if (mode & ISurfaceComposer::eElectronBeamAnimationOn) {
2282abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        electronBeamOnAnimationImplLocked();
2283abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    }
2284a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian
2285a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian    // make sure to redraw the whole screen when the animation is done
2286a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian    mDirtyRegion.set(hw.bounds());
228799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    signalTransaction();
2288a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian
2289015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian    return NO_ERROR;
22909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
22919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOn(int32_t mode)
22939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
22949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class MessageTurnElectronBeamOn : public MessageBase {
22959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        SurfaceFlinger* flinger;
2296abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        int32_t mode;
22979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        status_t result;
22989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
2299abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        MessageTurnElectronBeamOn(SurfaceFlinger* flinger, int32_t mode)
2300abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            : flinger(flinger), mode(mode), result(PERMISSION_DENIED) {
23019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
23029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        status_t getResult() const {
23039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return result;
23049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
23059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        virtual bool handler() {
23069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
2307abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            result = flinger->turnElectronBeamOnImplLocked(mode);
23089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return true;
23099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
23109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
23119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2312abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    postMessageAsync( new MessageTurnElectronBeamOn(this, mode) );
23139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
23149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
23159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
23169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// ---------------------------------------------------------------------------
23179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
231874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopianstatus_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy,
231974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        sp<IMemoryHeap>* heap,
232074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t* w, uint32_t* h, PixelFormat* f,
2321bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t sw, uint32_t sh,
2322bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ, uint32_t maxLayerZ)
232374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{
232474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    status_t result = PERMISSION_DENIED;
232574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
232674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // only one display supported for now
232799ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten    if (CC_UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
232874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return BAD_VALUE;
232974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
233074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
233174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return INVALID_OPERATION;
233274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
233374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // get screen geometry
233474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const DisplayHardware& hw(graphicPlane(dpy).displayHardware());
233574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const uint32_t hw_w = hw.getWidth();
233674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const uint32_t hw_h = hw.getHeight();
233774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
233874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    if ((sw > hw_w) || (sh > hw_h))
233974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return BAD_VALUE;
234074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
234174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    sw = (!sw) ? hw_w : sw;
234274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    sh = (!sh) ? hw_h : sh;
234374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const size_t size = sw * sh * 4;
234474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
23459d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block    //ALOGD("screenshot: sw=%d, sh=%d, minZ=%d, maxZ=%d",
23461c71a47a6db679a3212f0c99e14f330d6da500faMathias Agopian    //        sw, sh, minLayerZ, maxLayerZ);
2347c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
234874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // make sure to clear all GL error flags
234974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    while ( glGetError() != GL_NO_ERROR ) ;
235074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
235174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // create a FBO
235274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    GLuint name, tname;
235374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glGenRenderbuffersOES(1, &tname);
235474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindRenderbufferOES(GL_RENDERBUFFER_OES, tname);
235574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA8_OES, sw, sh);
235674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glGenFramebuffersOES(1, &name);
235774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
235874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES,
235974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, tname);
236074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
236174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
2362c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
236374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    if (status == GL_FRAMEBUFFER_COMPLETE_OES) {
236474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
236574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // invert everything, b/c glReadPixel() below will invert the FB
236674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glViewport(0, 0, sw, sh);
2367f653b897a449e10d6cbfb6e0812f7b0bb02d6482Mathias Agopian        glScissor(0, 0, sw, sh);
2368ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian        glEnable(GL_SCISSOR_TEST);
236974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_PROJECTION);
237074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glPushMatrix();
237174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glLoadIdentity();
2372ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian        glOrthof(0, hw_w, hw_h, 0, 0, 1);
237374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_MODELVIEW);
237474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
237574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // redraw the screen entirely...
237674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glClearColor(0,0,0,1);
237774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
2378f653b897a449e10d6cbfb6e0812f7b0bb02d6482Mathias Agopian
23799575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        const LayerVector& layers(mDrawingState.layersSortedByZ);
23809575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        const size_t count = layers.size();
238174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        for (size_t i=0 ; i<count ; ++i) {
238274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            const sp<LayerBase>& layer(layers[i]);
2383b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian            const uint32_t flags = layer->drawingState().flags;
2384b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian            if (!(flags & ISurfaceComposer::eLayerHidden)) {
2385b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                const uint32_t z = layer->drawingState().z;
2386b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                if (z >= minLayerZ && z <= maxLayerZ) {
2387b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                    layer->drawForSreenShot();
2388b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                }
2389bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian            }
239074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        }
239174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
239274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // XXX: this is needed on tegra
2393ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian        glEnable(GL_SCISSOR_TEST);
239474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glScissor(0, 0, sw, sh);
239574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
239674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // check for errors and return screen capture
239774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        if (glGetError() != GL_NO_ERROR) {
239874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // error while rendering
239974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            result = INVALID_OPERATION;
240074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        } else {
240174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // allocate shared memory large enough to hold the
240274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // screen capture
240374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            sp<MemoryHeapBase> base(
240474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    new MemoryHeapBase(size, 0, "screen-capture") );
240574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            void* const ptr = base->getBase();
240674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            if (ptr) {
240774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                // capture the screen with glReadPixels()
240874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                glReadPixels(0, 0, sw, sh, GL_RGBA, GL_UNSIGNED_BYTE, ptr);
240974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                if (glGetError() == GL_NO_ERROR) {
241074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *heap = base;
241174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *w = sw;
241274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *h = sh;
241374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *f = PIXEL_FORMAT_RGBA_8888;
241474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    result = NO_ERROR;
241574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                }
241674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            } else {
241774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                result = NO_MEMORY;
241874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            }
241974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        }
242074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glEnable(GL_SCISSOR_TEST);
242174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glViewport(0, 0, hw_w, hw_h);
242274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_PROJECTION);
242374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glPopMatrix();
242474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_MODELVIEW);
242574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    } else {
242674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        result = BAD_VALUE;
242774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    }
242874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
242974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // release FBO resources
243074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
243174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glDeleteRenderbuffersOES(1, &tname);
243274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glDeleteFramebuffersOES(1, &name);
2433e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian
2434e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian    hw.compositionComplete();
2435e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian
24369d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block    // ALOGD("screenshot: result = %s", result<0 ? strerror(result) : "OK");
2437c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
243874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    return result;
243974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian}
244074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
244174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
24421b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopianstatus_t SurfaceFlinger::captureScreen(DisplayID dpy,
24431b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        sp<IMemoryHeap>* heap,
244474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t* width, uint32_t* height, PixelFormat* format,
2445bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t sw, uint32_t sh,
2446bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ, uint32_t maxLayerZ)
24471b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian{
24481b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    // only one display supported for now
244999ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten    if (CC_UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
24501b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        return BAD_VALUE;
24511b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
24521b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
24531b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        return INVALID_OPERATION;
24541b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
24551b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    class MessageCaptureScreen : public MessageBase {
24561b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        SurfaceFlinger* flinger;
24571b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        DisplayID dpy;
24581b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        sp<IMemoryHeap>* heap;
24591b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        uint32_t* w;
24601b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        uint32_t* h;
24611b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        PixelFormat* f;
246274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t sw;
246374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t sh;
2464bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ;
2465bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t maxLayerZ;
24661b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        status_t result;
24671b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    public:
24681b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        MessageCaptureScreen(SurfaceFlinger* flinger, DisplayID dpy,
246974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                sp<IMemoryHeap>* heap, uint32_t* w, uint32_t* h, PixelFormat* f,
2470bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                uint32_t sw, uint32_t sh,
2471bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                uint32_t minLayerZ, uint32_t maxLayerZ)
24721b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            : flinger(flinger), dpy(dpy),
2473bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              heap(heap), w(w), h(h), f(f), sw(sw), sh(sh),
2474bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              minLayerZ(minLayerZ), maxLayerZ(maxLayerZ),
2475bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              result(PERMISSION_DENIED)
24761b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
24771b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
24781b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        status_t getResult() const {
24791b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            return result;
24801b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
24811b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        virtual bool handler() {
24821b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
24831b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
24841b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            // if we have secure windows, never allow the screen capture
24851b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            if (flinger->mSecureFrameBuffer)
24861b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                return true;
24871b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
248874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            result = flinger->captureScreenImplLocked(dpy,
2489bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                    heap, w, h, f, sw, sh, minLayerZ, maxLayerZ);
24901b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
24911b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            return true;
24921b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
24931b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    };
24941b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
24951b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    sp<MessageBase> msg = new MessageCaptureScreen(this,
2496bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian            dpy, heap, width, height, format, sw, sh, minLayerZ, maxLayerZ);
24971b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    status_t res = postMessageSync(msg);
24981b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    if (res == NO_ERROR) {
24991b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        res = static_cast<MessageCaptureScreen*>( msg.get() )->getResult();
25001b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    }
25011b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    return res;
25021b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian}
25031b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
25041b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// ---------------------------------------------------------------------------
25051b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
2506b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<Layer> SurfaceFlinger::getLayer(const sp<ISurface>& sur) const
2507edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2508b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<Layer> result;
2509b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    Mutex::Autolock _l(mStateLock);
2510b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    result = mLayerMap.valueFor( sur->asBinder() ).promote();
2511b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return result;
2512b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
25137303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
2514b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// ---------------------------------------------------------------------------
251596f0819f81293076e652792794a961543e6750d7Mathias Agopian
2516b7e930db175c192464cebdeb49eb56cf6dd60114Mathias AgopianClient::Client(const sp<SurfaceFlinger>& flinger)
2517b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    : mFlinger(flinger), mNameGenerator(1)
2518b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{
2519edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2520edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
252196f0819f81293076e652792794a961543e6750d7Mathias AgopianClient::~Client()
252296f0819f81293076e652792794a961543e6750d7Mathias Agopian{
252396f0819f81293076e652792794a961543e6750d7Mathias Agopian    const size_t count = mLayers.size();
252496f0819f81293076e652792794a961543e6750d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
252596f0819f81293076e652792794a961543e6750d7Mathias Agopian        sp<LayerBaseClient> layer(mLayers.valueAt(i).promote());
252696f0819f81293076e652792794a961543e6750d7Mathias Agopian        if (layer != 0) {
252796f0819f81293076e652792794a961543e6750d7Mathias Agopian            mFlinger->removeLayer(layer);
252896f0819f81293076e652792794a961543e6750d7Mathias Agopian        }
2529edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2530edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2531076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
253296f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t Client::initCheck() const {
2533b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return NO_ERROR;
2534edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2535076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
25364f113740180b6512b43723c4728f262882dc9b45Mathias Agopiansize_t Client::attachLayer(const sp<LayerBaseClient>& layer)
2537edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
25384f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    Mutex::Autolock _l(mLock);
25394f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    size_t name = mNameGenerator++;
254096f0819f81293076e652792794a961543e6750d7Mathias Agopian    mLayers.add(name, layer);
254196f0819f81293076e652792794a961543e6750d7Mathias Agopian    return name;
2542edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2543edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2544b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianvoid Client::detachLayer(const LayerBaseClient* layer)
254596f0819f81293076e652792794a961543e6750d7Mathias Agopian{
25464f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    Mutex::Autolock _l(mLock);
254796f0819f81293076e652792794a961543e6750d7Mathias Agopian    // we do a linear search here, because this doesn't happen often
254896f0819f81293076e652792794a961543e6750d7Mathias Agopian    const size_t count = mLayers.size();
254996f0819f81293076e652792794a961543e6750d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
255096f0819f81293076e652792794a961543e6750d7Mathias Agopian        if (mLayers.valueAt(i) == layer) {
255196f0819f81293076e652792794a961543e6750d7Mathias Agopian            mLayers.removeItemsAt(i, 1);
255296f0819f81293076e652792794a961543e6750d7Mathias Agopian            break;
255396f0819f81293076e652792794a961543e6750d7Mathias Agopian        }
255496f0819f81293076e652792794a961543e6750d7Mathias Agopian    }
255596f0819f81293076e652792794a961543e6750d7Mathias Agopian}
25564f113740180b6512b43723c4728f262882dc9b45Mathias Agopiansp<LayerBaseClient> Client::getLayerUser(int32_t i) const
25574f113740180b6512b43723c4728f262882dc9b45Mathias Agopian{
25584f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    Mutex::Autolock _l(mLock);
2559076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBaseClient> lbc;
25604f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    wp<LayerBaseClient> layer(mLayers.valueFor(i));
256196f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (layer != 0) {
256296f0819f81293076e652792794a961543e6750d7Mathias Agopian        lbc = layer.promote();
2563e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE_IF(lbc==0, "getLayerUser(name=%d) is dead", int(i));
2564076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
2565076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return lbc;
2566edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2567edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2568a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
2569a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianstatus_t Client::onTransact(
2570a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
2571a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian{
2572a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // these must be checked
2573a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     IPCThreadState* ipc = IPCThreadState::self();
2574a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     const int pid = ipc->getCallingPid();
2575a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     const int uid = ipc->getCallingUid();
2576a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     const int self_pid = getpid();
257799ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten     if (CC_UNLIKELY(pid != self_pid && uid != AID_GRAPHICS && uid != 0)) {
2578a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian         // we're called from a different process, do the real check
257999b49840d309727678b77403d6cc9f920111623fMathias Agopian         if (!PermissionCache::checkCallingPermission(sAccessSurfaceFlinger))
2580a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian         {
2581e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block             ALOGE("Permission Denial: "
2582a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                     "can't openGlobalTransaction pid=%d, uid=%d", pid, uid);
2583a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian             return PERMISSION_DENIED;
2584a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian         }
2585a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     }
2586a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     return BnSurfaceComposerClient::onTransact(code, data, reply, flags);
2587edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2588a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
2589a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
259096f0819f81293076e652792794a961543e6750d7Mathias Agopiansp<ISurface> Client::createSurface(
25910ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        ISurfaceComposerClient::surface_data_t* params,
2592b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        const String8& name,
2593b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
2594edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t flags)
2595edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2596b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    /*
2597a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     * createSurface must be called from the GL thread so that it can
2598a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     * have access to the GL context.
2599b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     */
2600b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
2601a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    class MessageCreateSurface : public MessageBase {
2602a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        sp<ISurface> result;
2603a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        SurfaceFlinger* flinger;
2604a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        ISurfaceComposerClient::surface_data_t* params;
2605a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        Client* client;
2606a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        const String8& name;
2607a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        DisplayID display;
2608a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        uint32_t w, h;
2609a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        PixelFormat format;
2610a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        uint32_t flags;
2611a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    public:
2612a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        MessageCreateSurface(SurfaceFlinger* flinger,
2613a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                ISurfaceComposerClient::surface_data_t* params,
2614a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                const String8& name, Client* client,
2615a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
2616a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                uint32_t flags)
2617a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            : flinger(flinger), params(params), client(client), name(name),
2618a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian              display(display), w(w), h(h), format(format), flags(flags)
2619a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        {
2620579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        }
2621a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        sp<ISurface> getResult() const { return result; }
2622a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        virtual bool handler() {
2623a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            result = flinger->createSurface(params, name, client,
2624a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                    display, w, h, format, flags);
2625a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            return true;
2626b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        }
2627a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    };
2628b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
2629a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    sp<MessageBase> msg = new MessageCreateSurface(mFlinger.get(),
2630a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            params, name, this, display, w, h, format, flags);
2631a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    mFlinger->postMessageSync(msg);
2632a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    return static_cast<MessageCreateSurface*>( msg.get() )->getResult();
2633b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
2634a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianstatus_t Client::destroySurface(SurfaceID sid) {
2635a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    return mFlinger->removeSurface(this, sid);
2636b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
2637b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
2638b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// ---------------------------------------------------------------------------
2639edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
26409a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::GraphicBufferAlloc() {}
26419a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
26429a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::~GraphicBufferAlloc() {}
26439a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
26449a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h,
2645d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        PixelFormat format, uint32_t usage, status_t* error) {
26469a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(w, h, format, usage));
26479a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    status_t err = graphicBuffer->initCheck();
2648d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian    *error = err;
2649a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (err != 0 || graphicBuffer->handle == 0) {
2650d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        if (err == NO_MEMORY) {
2651d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian            GraphicBuffer::dumpAllocationsToSystemLog();
2652d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        }
2653e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE("GraphicBufferAlloc::createGraphicBuffer(w=%d, h=%d) "
2654a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian             "failed (%s), handle=%p",
2655a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                w, h, strerror(-err), graphicBuffer->handle);
26569a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis        return 0;
26579a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    }
26589a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    return graphicBuffer;
26599a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis}
26609a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
26619a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis// ---------------------------------------------------------------------------
26629a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
2663edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane::GraphicPlane()
2664edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    : mHw(0)
2665edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2666edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2667edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2668edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane::~GraphicPlane() {
2669edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    delete mHw;
2670edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2671edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2672edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool GraphicPlane::initialized() const {
2673edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return mHw ? true : false;
2674edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2675edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
26762b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianint GraphicPlane::getWidth() const {
26772b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    return mWidth;
2678edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2679edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
26802b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianint GraphicPlane::getHeight() const {
26812b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    return mHeight;
26822b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian}
26832b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
26842b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianvoid GraphicPlane::setDisplayHardware(DisplayHardware *hw)
26852b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian{
26862b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mHw = hw;
26872b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
26882b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    // initialize the display orientation transform.
26892b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    // it's a constant that should come from the display driver.
26902b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    int displayOrientation = ISurfaceComposer::eOrientationDefault;
26912b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    char property[PROPERTY_VALUE_MAX];
26922b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    if (property_get("ro.sf.hwrotation", property, NULL) > 0) {
26932b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        //displayOrientation
26942b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        switch (atoi(property)) {
26952b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        case 90:
26962b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            displayOrientation = ISurfaceComposer::eOrientation90;
26972b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            break;
26982b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        case 270:
26992b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            displayOrientation = ISurfaceComposer::eOrientation270;
27002b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            break;
27012b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        }
27022b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    }
27032b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
27042b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float w = hw->getWidth();
27052b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float h = hw->getHeight();
27062b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    GraphicPlane::orientationToTransfrom(displayOrientation, w, h,
27072b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            &mDisplayTransform);
27082b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    if (displayOrientation & ISurfaceComposer::eOrientationSwapMask) {
27092b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayWidth = h;
27102b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayHeight = w;
27112b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    } else {
27122b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayWidth = w;
27132b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayHeight = h;
27142b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    }
27152b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
27162b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    setOrientation(ISurfaceComposer::eOrientationDefault);
2717edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2718edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2719edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t GraphicPlane::orientationToTransfrom(
2720edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int orientation, int w, int h, Transform* tr)
2721eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian{
2722eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    uint32_t flags = 0;
2723edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (orientation) {
2724edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientationDefault:
2725eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_0;
2726eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        break;
2727edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientation90:
2728eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_90;
2729edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
2730edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientation180:
2731eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_180;
2732edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
2733edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientation270:
2734eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_270;
2735edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
2736edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    default:
2737edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return BAD_VALUE;
2738edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2739eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    tr->set(flags, w, h);
2740edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
2741edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2742edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2743edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t GraphicPlane::setOrientation(int orientation)
2744edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2745edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // If the rotation can be handled in hardware, this is where
2746edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // the magic should happen.
27472b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
27482b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const DisplayHardware& hw(displayHardware());
27492b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float w = mDisplayWidth;
27502b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float h = mDisplayHeight;
27512b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mWidth = int(w);
27522b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mHeight = int(h);
27532b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
27542b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    Transform orientationTransform;
2755eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    GraphicPlane::orientationToTransfrom(orientation, w, h,
2756eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian            &orientationTransform);
2757eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    if (orientation & ISurfaceComposer::eOrientationSwapMask) {
2758eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        mWidth = int(h);
2759eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        mHeight = int(w);
2760edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2761eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian
27620d1318b974feba2e6ff13e36a1781343c2fce045Mathias Agopian    mOrientation = orientation;
27632b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mGlobalTransform = mDisplayTransform * orientationTransform;
2764edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
2765edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2766edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2767edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst DisplayHardware& GraphicPlane::displayHardware() const {
2768edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return *mHw;
2769edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2770edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
277159119e658a12279e8fff508f8773843de2d90917Mathias AgopianDisplayHardware& GraphicPlane::editDisplayHardware() {
277259119e658a12279e8fff508f8773843de2d90917Mathias Agopian    return *mHw;
277359119e658a12279e8fff508f8773843de2d90917Mathias Agopian}
277459119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2775edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst Transform& GraphicPlane::transform() const {
2776edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return mGlobalTransform;
2777edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2778edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2779076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias AgopianEGLDisplay GraphicPlane::getEGLDisplay() const {
2780076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return mHw->getEGLDisplay();
2781076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
2782076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
2783edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
2784edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2785edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
2786