SurfaceFlinger.cpp revision 22ffb117b0c2a906bd04aef9738a52223cdd1dce
1edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/*
2edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
3edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
4edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * you may not use this file except in compliance with the License.
6edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * You may obtain a copy of the License at
7edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
8edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
10edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * See the License for the specific language governing permissions and
14edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * limitations under the License.
15edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */
16edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
171c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#define ATRACE_TAG ATRACE_TAG_GRAPHICS
181c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
19edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdlib.h>
20edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdio.h>
21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdint.h>
22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <unistd.h>
23edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <fcntl.h>
24edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <errno.h>
25edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <math.h>
26a837ba778f2d7a5170b37aa33624d9b9711c354dJean-Baptiste Queru#include <limits.h>
27edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/types.h>
28edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/stat.h>
29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/ioctl.h>
30edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/log.h>
32edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/properties.h>
33edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
34c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IPCThreadState.h>
35c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IServiceManager.h>
367303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian#include <binder/MemoryHeapBase.h>
3799b49840d309727678b77403d6cc9f920111623fMathias Agopian#include <binder/PermissionCache.h>
387303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
39d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian#include <gui/IDisplayEventConnection.h>
40d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
41edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String8.h>
42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String16.h>
43edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/StopWatch.h>
441c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#include <utils/Trace.h>
45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
463330b203039dea366d4981db1408a460134b2d2cMathias Agopian#include <ui/GraphicBufferAllocator.h>
47edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/PixelFormat.h>
48edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <GLES/gl.h>
50edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h"
5290ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include "DdmConnection.h"
53d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian#include "EventThread.h"
541f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian#include "GLExtensions.h"
55edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h"
56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerDim.h"
57118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian#include "LayerScreenshot.h"
58edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h"
59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
60edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "DisplayHardware/DisplayHardware.h"
61a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian#include "DisplayHardware/HWComposer.h"
62edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
631db13d79518f600d65a4fc006fe42900b890966eGlenn Kasten#include <private/android_filesystem_config.h>
6490ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include <private/gui/SharedBufferStack.h>
65a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
66bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian#define EGL_VERSION_HW_ANDROID  0x3143
67bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
68edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DISPLAY_COUNT       1
69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
7399b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sHardwareTest("android.permission.HARDWARE_TEST");
7499b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER");
7599b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER");
7699b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sDump("android.permission.DUMP");
7799b49840d309727678b77403d6cc9f920111623fMathias Agopian
7899b49840d309727678b77403d6cc9f920111623fMathias Agopian// ---------------------------------------------------------------------------
7999b49840d309727678b77403d6cc9f920111623fMathias Agopian
80edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::SurfaceFlinger()
81edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    :   BnSurfaceComposer(), Thread(false),
82edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mTransactionFlags(0),
8328378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        mTransationPending(false),
84076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved(false),
85edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mBootTime(systemTime()),
86edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mVisibleRegionsDirty(false),
87a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        mHwWorkListDirty(false),
88abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        mElectronBeamAnimationMode(0),
89edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDebugRegion(0),
90edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDebugBackground(0),
918afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian        mDebugDDMS(0),
9273d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian        mDebugDisableHWC(0),
93a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian        mDebugDisableTransformHint(0),
949795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInSwapBuffers(0),
959795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastSwapBufferTime(0),
969795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInTransaction(0),
979795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastTransactionTime(0),
983330b203039dea366d4981db1408a460134b2d2cMathias Agopian        mBootFinished(false),
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
1173854ed549012f2abf8fea7b0e6db30b104ea5547Colin Cross#ifdef DDMS_DEBUGGING
1188afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    property_get("debug.sf.ddms", value, "0");
1198afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    mDebugDDMS = atoi(value);
1208afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    if (mDebugDDMS) {
1218afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian        DdmConnection::start(getServiceName());
1228afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    }
1233854ed549012f2abf8fea7b0e6db30b104ea5547Colin Cross#endif
1248afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
125a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI_IF(mDebugRegion,       "showupdates enabled");
126a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI_IF(mDebugBackground,   "showbackground enabled");
127a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI_IF(mDebugDDMS,         "DDMS debugging enabled");
128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
13099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::onFirstRef()
13199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
13299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.init(this);
13399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
13499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY);
13599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
13699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // Wait for the main thread to be done with its initialization
13799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mReadyToRunBarrier.wait();
13899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
13999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
14099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
141edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::~SurfaceFlinger()
142edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
143edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDeleteTextures(1, &mWormholeTexName);
144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
145edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
14699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::binderDied(const wp<IBinder>& who)
14799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
14899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // the window manager died on us. prepare its eulogy.
14999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
15099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // reset screen orientation
15199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    Vector<ComposerState> state;
15299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    setTransactionState(state, eOrientationDefault, 0);
15399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
15499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // restart the boot-animation
15599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    property_set("ctl.start", "bootanim");
15699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
15799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
1587303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopiansp<IMemoryHeap> SurfaceFlinger::getCblk() const
159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1607303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    return mServerHeap;
161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1637e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopiansp<ISurfaceComposerClient> SurfaceFlinger::createConnection()
164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
16596f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<ISurfaceComposerClient> bclient;
16696f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<Client> client(new Client(this));
16796f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = client->initCheck();
16896f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR) {
16996f0819f81293076e652792794a961543e6750d7Mathias Agopian        bclient = client;
170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return bclient;
172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1749a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc()
1759a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis{
1769a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc());
1779a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    return gba;
1789a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis}
179b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst GraphicPlane& SurfaceFlinger::graphicPlane(int dpy) const
181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
182e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block    ALOGE_IF(uint32_t(dpy) >= DISPLAY_COUNT, "Invalid DisplayID %d", dpy);
183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(mGraphicPlanes[dpy]);
184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return plane;
185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane& SurfaceFlinger::graphicPlane(int dpy)
188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return const_cast<GraphicPlane&>(
190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const_cast<SurfaceFlinger const *>(this)->graphicPlane(dpy));
191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::bootFinished()
194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
195edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t now = systemTime();
196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t duration = now - mBootTime;
197a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
1983330b203039dea366d4981db1408a460134b2d2cMathias Agopian    mBootFinished = true;
1991f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
2001f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // wait patiently for the window manager death
2011f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    const String16 name("window");
2021f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    sp<IBinder> window(defaultServiceManager()->getService(name));
2031f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    if (window != 0) {
2041f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian        window->linkToDeath(this);
2051f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    }
2061f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
2071f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // stop boot animation
208a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    property_set("ctl.stop", "bootanim");
209edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
210edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic inline uint16_t pack565(int r, int g, int b) {
212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return (r<<11)|(g<<5)|b;
213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::readyToRun()
216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
217a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI(   "SurfaceFlinger's main thread ready to run. "
218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            "Initializing graphics H/W...");
219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // we only support one display currently
221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int dpy = 0;
222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    {
224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // initialize the main display
225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GraphicPlane& plane(graphicPlane(dpy));
226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        DisplayHardware* const hw = new DisplayHardware(this, dpy);
227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        plane.setDisplayHardware(hw);
228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2307303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    // create the shared control-block
2317303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    mServerHeap = new MemoryHeapBase(4096,
2327303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian            MemoryHeapBase::READ_ONLY, "SurfaceFlinger read-only heap");
233e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block    ALOGE_IF(mServerHeap==0, "can't create shared memory dealer");
2348b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
2357303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    mServerCblk = static_cast<surface_flinger_cblk_t*>(mServerHeap->getBase());
236e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block    ALOGE_IF(mServerCblk==0, "can't get to shared control block's address");
2378b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
2387303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    new(mServerCblk) surface_flinger_cblk_t;
2397303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize primary screen
241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // (other display should be initialized in the same manner, but
242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // asynchronously, as they could come and go. None of this is supported
243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // yet).
244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(graphicPlane(dpy));
245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw = plane.displayHardware();
246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint32_t w = hw.getWidth();
247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint32_t h = hw.getHeight();
248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint32_t f = hw.getFormat();
249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    hw.makeCurrent();
250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize the shared control block
252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mServerCblk->connected |= 1<<dpy;
253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    display_cblk_t* dcblk = mServerCblk->displays + dpy;
254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    memset(dcblk, 0, sizeof(display_cblk_t));
2552b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    dcblk->w            = plane.getWidth();
2562b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    dcblk->h            = plane.getHeight();
257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->format       = f;
258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->orientation  = ISurfaceComposer::eOrientationDefault;
259edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->xdpi         = hw.getDpiX();
260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->ydpi         = hw.getDpiY();
261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->fps          = hw.getRefreshRate();
262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->density      = hw.getDensity();
263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // Initialize OpenGL|ES
265edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
2668b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber    glPixelStorei(GL_PACK_ALIGNMENT, 4);
267edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glEnableClientState(GL_VERTEX_ARRAY);
268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glEnable(GL_SCISSOR_TEST);
269edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glShadeModel(GL_FLAT);
270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_DITHER);
271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_CULL_FACE);
272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint16_t g0 = pack565(0x0F,0x1F,0x0F);
274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint16_t g1 = pack565(0x17,0x2f,0x17);
2759575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    const uint16_t wormholeTexData[4] = { g0, g1, g1, g0 };
276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glGenTextures(1, &mWormholeTexName);
277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glBindTexture(GL_TEXTURE_2D, mWormholeTexName);
278edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0,
2839575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis            GL_RGB, GL_UNSIGNED_SHORT_5_6_5, wormholeTexData);
2849575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis
2859575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    const uint16_t protTexData[] = { pack565(0x03, 0x03, 0x03) };
2869575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glGenTextures(1, &mProtectedTexName);
2879575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glBindTexture(GL_TEXTURE_2D, mProtectedTexName);
2889575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2899575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2909575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
2919575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
2929575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0,
2939575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis            GL_RGB, GL_UNSIGNED_SHORT_5_6_5, protTexData);
294edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
295edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glViewport(0, 0, w, h);
296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glMatrixMode(GL_PROJECTION);
297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glLoadIdentity();
298ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    // put the origin in the left-bottom corner
299ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    glOrthof(0, w, 0, h, 0, 1); // l=0, r=w ; b=0, t=h
300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
301d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
302d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian    // start the EventThread
303d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian    mEventThread = new EventThread(this);
3048aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian    mEventQueue.setEventThread(mEventThread);
305f6de1c04ffc2c7a739578b7612944fddb7011ab7Mathias Agopian    hw.startSleepManagement();
306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     *  We're now ready to accept clients...
309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
310edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
311d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian    mReadyToRunBarrier.open();
312d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
313a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    // start boot animation
314a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    property_set("ctl.start", "bootanim");
3158b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
320d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
321582270d69db94286a248bd829f1ae6f910d45124Jamie Gennisbool SurfaceFlinger::authenticateSurfaceTexture(
322582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis        const sp<ISurfaceTexture>& surfaceTexture) const {
323134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    Mutex::Autolock _l(mStateLock);
324582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis    sp<IBinder> surfaceTextureBinder(surfaceTexture->asBinder());
325134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
326134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // Check the visible layer list for the ISurface
327134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
328134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    size_t count = currentLayers.size();
329134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    for (size_t i=0 ; i<count ; i++) {
330134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        const sp<LayerBase>& layer(currentLayers[i]);
331134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        sp<LayerBaseClient> lbc(layer->getLayerBaseClient());
332582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis        if (lbc != NULL) {
333582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder();
334582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            if (lbcBinder == surfaceTextureBinder) {
335582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis                return true;
336582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            }
337134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        }
338134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    }
339134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
340134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // Check the layers in the purgatory.  This check is here so that if a
341582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis    // SurfaceTexture gets destroyed before all the clients are done using it,
342582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis    // the error will not be reported as "surface XYZ is not authenticated", but
343134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // will instead fail later on when the client tries to use the surface,
344134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // which should be reported as "surface XYZ returned an -ENODEV".  The
345134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // purgatorized layers are no less authentic than the visible ones, so this
346134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // should not cause any harm.
347134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    size_t purgatorySize =  mLayerPurgatory.size();
348134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    for (size_t i=0 ; i<purgatorySize ; i++) {
349134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
350134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        sp<LayerBaseClient> lbc(layer->getLayerBaseClient());
351582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis        if (lbc != NULL) {
352582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder();
353582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            if (lbcBinder == surfaceTextureBinder) {
354582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis                return true;
355582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            }
356134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        }
357134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    }
358134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
359134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    return false;
360134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis}
361134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
362d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian// ----------------------------------------------------------------------------
363d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
364d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopiansp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection() {
3658aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian    return mEventThread->createEventConnection();
366bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian}
367bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
368edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
36999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
37099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::waitForEvent() {
37199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.waitMessage();
37299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
37399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
37499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalTransaction() {
37599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.invalidate();
37699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
37799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
37899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalLayerUpdate() {
37999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.invalidate();
38099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
38199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
38299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalRefresh() {
38399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.refresh();
38499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
38599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
38699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg,
38799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        nsecs_t reltime, uint32_t flags) {
38899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return mEventQueue.postMessage(msg, reltime);
38999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
39099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
39199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,
39299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        nsecs_t reltime, uint32_t flags) {
39399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    status_t res = mEventQueue.postMessage(msg, reltime);
39499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    if (res == NO_ERROR) {
39599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        msg->wait();
39699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    }
39799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return res;
39899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
399edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
400edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool SurfaceFlinger::threadLoop()
401edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
402edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    waitForEvent();
40399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return true;
40499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
405edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
40699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::onMessageReceived(int32_t what)
40799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
4081c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
40999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    switch (what) {
410303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian        case MessageQueue::REFRESH: {
411303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian//        case MessageQueue::INVALIDATE: {
41299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            // if we're in a global transaction, don't do anything.
41399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
41499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            uint32_t transactionFlags = peekTransactionFlags(mask);
41599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            if (CC_UNLIKELY(transactionFlags)) {
41699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian                handleTransaction(transactionFlags);
41799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            }
418edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
41999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            // post surfaces (if needed)
42099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            handlePageFlip();
421edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
422303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian//            signalRefresh();
423303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian//
424303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian//        } break;
425303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian//
426303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian//        case MessageQueue::REFRESH: {
4273a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian
428c9ca7011501cb8730ce4e6e527cb402adb7a0178Mathias Agopian            handleRefresh();
429a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
430303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian            const DisplayHardware& hw(graphicPlane(0).displayHardware());
431303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian
432303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian//            if (mDirtyRegion.isEmpty()) {
433303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian//                return;
434303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian//            }
435303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian
436b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian            if (CC_UNLIKELY(mHwWorkListDirty)) {
437b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian                // build the h/w work list
438b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian                handleWorkList();
439b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian            }
440303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian
441b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian            if (CC_LIKELY(hw.canDraw())) {
442b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian                // repaint the framebuffer (if needed)
443b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian                handleRepaint();
444b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian                // inform the h/w that we're done compositing
445b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian                hw.compositionComplete();
446b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian                postFramebuffer();
447c9ca7011501cb8730ce4e6e527cb402adb7a0178Mathias Agopian            } else {
448b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian                // pretend we did the post
449c9ca7011501cb8730ce4e6e527cb402adb7a0178Mathias Agopian                hw.compositionComplete();
45099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            }
451b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian
45299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        } break;
453edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
454edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
455edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
456edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer()
457edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
458841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
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::handleTransaction(uint32_t transactionFlags)
480edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
481841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
482841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
483ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    Mutex::Autolock _l(mStateLock);
484ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    const nsecs_t now = systemTime();
485ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = now;
486ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
487ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // Here we're guaranteed that some transaction flags are set
488ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // so we can call handleTransactionLocked() unconditionally.
489ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // We call getTransactionFlags(), which will also clear the flags,
490ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // with mStateLock held to guarantee that mCurrentState won't change
491ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // until the transaction is committed.
492ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
493ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
494ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    transactionFlags = getTransactionFlags(mask);
495ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    handleTransactionLocked(transactionFlags);
496ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
497ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mLastTransactionTime = systemTime() - now;
498ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = 0;
499ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    invalidateHwcGeometry();
500ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // here the transaction has been committed
5013d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian}
502edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
503ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopianvoid SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
5043d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{
5053d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    const LayerVector& currentLayers(mCurrentState.layersSortedByZ);
506edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t count = currentLayers.size();
507edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
508edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
509edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Traversal of the children
510edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * (perform the transaction for each of them if needed)
511edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
512edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
513edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const bool layersNeedTransaction = transactionFlags & eTraversalNeeded;
514edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (layersNeedTransaction) {
515edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (size_t i=0 ; i<count ; i++) {
516076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            const sp<LayerBase>& layer = currentLayers[i];
517edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
518edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (!trFlags) continue;
519edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
520edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const uint32_t flags = layer->doTransaction(0);
521edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (flags & Layer::eVisibleRegion)
522edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mVisibleRegionsDirty = true;
523edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
524edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
525edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
526edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
527edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Perform our own transaction if needed
528edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
529edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
530edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (transactionFlags & eTransactionNeeded) {
531edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (mCurrentState.orientation != mDrawingState.orientation) {
532edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // the orientation has changed, recompute all visible regions
533edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // and invalidate everything.
534edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
535edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int dpy = 0;
536edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int orientation = mCurrentState.orientation;
53721230c6410bdab13cd2bd274da54b1e4061b6035Jeff Brown            // Currently unused: const uint32_t flags = mCurrentState.orientationFlags;
538edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            GraphicPlane& plane(graphicPlane(dpy));
539edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            plane.setOrientation(orientation);
540edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
541edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // update the shared control block
542edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const DisplayHardware& hw(plane.displayHardware());
543edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            volatile display_cblk_t* dcblk = mServerCblk->displays + dpy;
544edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dcblk->orientation = orientation;
5452b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            dcblk->w = plane.getWidth();
5462b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            dcblk->h = plane.getHeight();
547edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
548edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
549edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mDirtyRegion.set(hw.bounds());
550edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
551edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5520aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        if (currentLayers.size() > mDrawingState.layersSortedByZ.size()) {
5530aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            // layers have been added
554edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
555edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
556edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5570aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        // some layers might have been removed, so
5580aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        // we need to update the regions they're exposing.
5590aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        if (mLayersRemoved) {
56048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian            mLayersRemoved = false;
561edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
5620aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            const LayerVector& previousLayers(mDrawingState.layersSortedByZ);
5633d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian            const size_t count = previousLayers.size();
5643d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian            for (size_t i=0 ; i<count ; i++) {
5650aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                const sp<LayerBase>& layer(previousLayers[i]);
5660aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                if (currentLayers.indexOf( layer ) < 0) {
5670aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                    // this layer is not visible anymore
5685d7126b625c8c4a7b945e8c247b63abff7bc13b6Mathias Agopian                    mDirtyRegionRemovedLayer.orSelf(layer->visibleRegionScreen);
5690aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                }
5700aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            }
571edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
572edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
573edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
574edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    commitTransaction();
575edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
576edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
577edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::computeVisibleRegions(
5781bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian    const LayerVector& currentLayers, Region& dirtyRegion, Region& opaqueRegion)
579edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
580841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
581841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
582edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(graphicPlane(0));
583edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Transform& planeTransform(plane.transform());
584ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian    const DisplayHardware& hw(plane.displayHardware());
585ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian    const Region screenRegion(hw.bounds());
586edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
587edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveOpaqueLayers;
588edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveCoveredLayers;
589edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region dirty;
590edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
591edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    bool secureFrameBuffer = false;
592edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
593edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t i = currentLayers.size();
594edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    while (i--) {
595076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        const sp<LayerBase>& layer = currentLayers[i];
596edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->validateVisibility(planeTransform);
597edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
598edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // start with the whole surface at its current location
599970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian        const Layer::State& s(layer->drawingState());
600edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
601ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
602ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * opaqueRegion: area of a surface that is fully opaque.
603ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
604edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region opaqueRegion;
605ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
606ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
607ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visibleRegion: area of a surface that is visible on screen
608ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * and not fully transparent. This is essentially the layer's
609ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * footprint minus the opaque regions above it.
610ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * Areas covered by a translucent surface are considered visible.
611ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
612edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region visibleRegion;
613ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
614ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
615ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * coveredRegion: area of a surface that is covered by all
616ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visible regions above it (which includes the translucent areas).
617ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
618edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region coveredRegion;
619ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
620ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
621ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // handle hidden surfaces by setting the visible region to empty
62299ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten        if (CC_LIKELY(!(s.flags & ISurfaceComposer::eLayerHidden) && s.alpha)) {
623a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            const bool translucent = !layer->isOpaque();
624970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian            const Rect bounds(layer->visibleBounds());
625edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            visibleRegion.set(bounds);
626ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            visibleRegion.andSelf(screenRegion);
627ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            if (!visibleRegion.isEmpty()) {
628ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // Remove the transparent area from the visible region
629ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (translucent) {
630ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    visibleRegion.subtractSelf(layer->transparentRegionScreen);
631ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
632edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
633ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // compute the opaque region
634ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                const int32_t layerOrientation = layer->getOrientation();
635ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (s.alpha==255 && !translucent &&
636ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                        ((layerOrientation & Transform::ROT_INVALID) == false)) {
637ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    // the opaque region is the layer's footprint
638ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    opaqueRegion = visibleRegion;
639ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
640edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
641edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
642edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
643ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Clip the covered region to the visible region
644ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        coveredRegion = aboveCoveredLayers.intersect(visibleRegion);
645ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
646ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveCoveredLayers for next (lower) layer
647ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        aboveCoveredLayers.orSelf(visibleRegion);
648ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
649edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // subtract the opaque region covered by the layers above us
650edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        visibleRegion.subtractSelf(aboveOpaqueLayers);
651edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
652edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // compute this layer's dirty region
653edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (layer->contentDirty) {
654edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // we need to invalidate the whole region
655edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dirty = visibleRegion;
656edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // as well, as the old visible region
657edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dirty.orSelf(layer->visibleRegionScreen);
658edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->contentDirty = false;
659edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
660a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian            /* compute the exposed region:
661ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   the exposed region consists of two components:
662ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   1) what's VISIBLE now and was COVERED before
663ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   2) what's EXPOSED now less what was EXPOSED before
664ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
665ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * note that (1) is conservative, we start with the whole
666ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * visible region but only keep what used to be covered by
667ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * something -- which mean it may have been exposed.
668ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
669ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * (2) handles areas that were not covered by anything but got
670ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * exposed because of a resize.
671a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian             */
672ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region newExposed = visibleRegion - coveredRegion;
673ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldVisibleRegion = layer->visibleRegionScreen;
674ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldCoveredRegion = layer->coveredRegionScreen;
675ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldExposed = oldVisibleRegion - oldCoveredRegion;
676ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed);
677edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
678edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirty.subtractSelf(aboveOpaqueLayers);
679edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
680edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // accumulate to the screen dirty region
681edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirtyRegion.orSelf(dirty);
682edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
683ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveOpaqueLayers for next (lower) layer
684edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        aboveOpaqueLayers.orSelf(opaqueRegion);
6858b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
686edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // Store the visible region is screen space
687edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setVisibleRegion(visibleRegion);
688edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setCoveredRegion(coveredRegion);
689edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
690970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian        // If a secure layer is partially visible, lock-down the screen!
691edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (layer->isSecure() && !visibleRegion.isEmpty()) {
692edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            secureFrameBuffer = true;
693edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
694edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
695edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
696970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian    // invalidate the areas where a layer was removed
697970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian    dirtyRegion.orSelf(mDirtyRegionRemovedLayer);
698970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian    mDirtyRegionRemovedLayer.clear();
699970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian
700edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mSecureFrameBuffer = secureFrameBuffer;
701edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    opaqueRegion = aboveOpaqueLayers;
702edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
703edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
704edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
705edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::commitTransaction()
706edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
7072f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall    if (!mLayersPendingRemoval.isEmpty()) {
7082f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall        // Notify removed layers now that they can't be drawn from
7092f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall        for (size_t i = 0; i < mLayersPendingRemoval.size(); i++) {
7102f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall            mLayersPendingRemoval[i]->onRemoved();
7112f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall        }
7122f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall        mLayersPendingRemoval.clear();
7132f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall    }
7142f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall
715edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDrawingState = mCurrentState;
71628378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    mTransationPending = false;
717cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mTransactionCV.broadcast();
718edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
719edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
720edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handlePageFlip()
721edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
7221c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
72399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    const DisplayHardware& hw = graphicPlane(0).displayHardware();
72499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    const Region screenRegion(hw.bounds());
72599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
7261bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian    const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
72799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    const bool visibleRegions = lockPageFlip(currentLayers);
728edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
72999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        if (visibleRegions || mVisibleRegionsDirty) {
730edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            Region opaqueRegion;
731edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            computeVisibleRegions(currentLayers, mDirtyRegion, opaqueRegion);
7324da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
7334da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            /*
7344da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian             *  rebuild the visible layer list
7354da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian             */
7361bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian            const size_t count = currentLayers.size();
7374da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            mVisibleLayersSortedByZ.clear();
7384da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            mVisibleLayersSortedByZ.setCapacity(count);
7394da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            for (size_t i=0 ; i<count ; i++) {
7404da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian                if (!currentLayers[i]->visibleRegionScreen.isEmpty())
7414da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian                    mVisibleLayersSortedByZ.add(currentLayers[i]);
7424da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            }
7434da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
744edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mWormholeRegion = screenRegion.subtract(opaqueRegion);
745edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = false;
746ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian            invalidateHwcGeometry();
747edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
748edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
749edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    unlockPageFlip(currentLayers);
7500dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian
7510dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    mDirtyRegion.orSelf(getAndClearInvalidateRegion());
752edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDirtyRegion.andSelf(screenRegion);
753edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
754edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
755ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopianvoid SurfaceFlinger::invalidateHwcGeometry()
756ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian{
757ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian    mHwWorkListDirty = true;
758ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian}
759ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian
760edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool SurfaceFlinger::lockPageFlip(const LayerVector& currentLayers)
761edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
762edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    bool recomputeVisibleRegions = false;
763edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t count = currentLayers.size();
764076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBase> const* layers = currentLayers.array();
765edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (size_t i=0 ; i<count ; i++) {
766b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
767edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->lockPageFlip(recomputeVisibleRegions);
768edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
769edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return recomputeVisibleRegions;
770edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
771edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
772edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::unlockPageFlip(const LayerVector& currentLayers)
773edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
774edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(graphicPlane(0));
775edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Transform& planeTransform(plane.transform());
77699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    const size_t count = currentLayers.size();
777076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBase> const* layers = currentLayers.array();
778edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (size_t i=0 ; i<count ; i++) {
779b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
780edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->unlockPageFlip(planeTransform, mDirtyRegion);
781edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
782edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
783edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
78499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::handleRefresh()
78599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
78699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    bool needInvalidate = false;
78799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
78899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    const size_t count = currentLayers.size();
78999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
79099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
79199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        if (layer->onPreComposition()) {
79299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            needInvalidate = true;
79399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        }
79499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    }
79599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    if (needInvalidate) {
79699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        signalLayerUpdate();
79799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    }
79899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
79999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
80099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
801a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopianvoid SurfaceFlinger::handleWorkList()
802a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian{
803a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    mHwWorkListDirty = false;
804a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    HWComposer& hwc(graphicPlane(0).displayHardware().getHwComposer());
805a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    if (hwc.initCheck() == NO_ERROR) {
806a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        const Vector< sp<LayerBase> >& currentLayers(mVisibleLayersSortedByZ);
807a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        const size_t count = currentLayers.size();
808a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        hwc.createWorkList(count);
80945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        hwc_layer_t* const cur(hwc.getLayers());
81045721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        for (size_t i=0 ; cur && i<count ; i++) {
81145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            currentLayers[i]->setGeometry(&cur[i]);
81253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian            if (mDebugDisableHWC || mDebugRegion) {
81373d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian                cur[i].compositionType = HWC_FRAMEBUFFER;
81473d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian                cur[i].flags |= HWC_SKIP_LAYER;
81573d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian            }
816a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        }
817a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
818a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian}
819b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian
820edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleRepaint()
821edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
822841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
823841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
824b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // compute the invalid region
8250656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian    mSwapRegion.orSelf(mDirtyRegion);
826edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
82799ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten    if (CC_UNLIKELY(mDebugRegion)) {
828edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        debugFlashRegions();
829edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
830edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
831b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // set the frame buffer
832b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
833b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    glMatrixMode(GL_MODELVIEW);
834b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    glLoadIdentity();
835edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
836edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t flags = hw.getFlags();
8378b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber    if ((flags & DisplayHardware::SWAP_RECTANGLE) ||
8388b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber        (flags & DisplayHardware::BUFFER_PRESERVED))
839df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian    {
84029d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // we can redraw only what's dirty, but since SWAP_RECTANGLE only
84129d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // takes a rectangle, we must make sure to update that whole
84229d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // rectangle in that case
84329d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        if (flags & DisplayHardware::SWAP_RECTANGLE) {
844b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            // TODO: we really should be able to pass a region to
84529d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // SWAP_RECTANGLE so that we don't have to redraw all this.
8460656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian            mDirtyRegion.set(mSwapRegion.bounds());
84729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        } else {
84829d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // in the BUFFER_PRESERVED case, obviously, we can update only
84929d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // what's needed and nothing more.
85029d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // NOTE: this is NOT a common case, as preserving the backbuffer
85129d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // is costly and usually involves copying the whole update back.
85229d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        }
853edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
85495a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian        if (flags & DisplayHardware::PARTIAL_UPDATES) {
85529d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // We need to redraw the rectangle that will be updated
856df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian            // (pushed to the framebuffer).
85795a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian            // This is needed because PARTIAL_UPDATES only takes one
85829d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // rectangle instead of a region (see DisplayHardware::flip())
8590656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian            mDirtyRegion.set(mSwapRegion.bounds());
860edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
86129d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // we need to redraw everything (the whole screen)
862edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mDirtyRegion.set(hw.bounds());
8630656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian            mSwapRegion = mDirtyRegion;
864edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
865edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
866edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
8679c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    setupHardwareComposer(mDirtyRegion);
868edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    composeSurfaces(mDirtyRegion);
869edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
8709c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    // update the swap region and clear the dirty region
8719c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    mSwapRegion.orSelf(mDirtyRegion);
872edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDirtyRegion.clear();
873edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
874edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
8759c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopianvoid SurfaceFlinger::setupHardwareComposer(Region& dirtyInOut)
876edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
877f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
878f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    HWComposer& hwc(hw.getHwComposer());
879f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    hwc_layer_t* const cur(hwc.getLayers());
880f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    if (!cur) {
8819c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        return;
882edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
883a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
8844da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian    const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
88545721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    size_t count = layers.size();
886a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
887e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block    ALOGE_IF(hwc.getNumLayers() != count,
88845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            "HAL number of layers (%d) doesn't match surfaceflinger (%d)",
88945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            hwc.getNumLayers(), count);
890a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
89145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    // just to be extra-safe, use the smallest count
89224925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling    if (hwc.initCheck() == NO_ERROR) {
89324925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling        count = count < hwc.getNumLayers() ? count : hwc.getNumLayers();
89424925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling    }
895a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
89645721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    /*
89745721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     *  update the per-frame h/w composer data for each layer
89845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     *  and build the transparent region of the FB
89945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     */
900f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
901f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
902f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        layer->setPerFrameData(&cur[i]);
903f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    }
9049c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    const size_t fbLayerCount = hwc.getLayerCount(HWC_FRAMEBUFFER);
905f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    status_t err = hwc.prepare();
906e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block    ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
907f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian
908f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    if (err == NO_ERROR) {
9099c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // what's happening here is tricky.
9109c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // we want to clear all the layers with the CLEAR_FB flags
9119c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // that are opaque.
9129c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // however, since some GPU are efficient at preserving
9139c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // the backbuffer, we want to take advantage of that so we do the
9149c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // clear only in the dirty region (other areas will be preserved
9159c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // on those GPUs).
9169c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        //   NOTE: on non backbuffer preserving GPU, the dirty region
9179c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        //   has already been expanded as needed, so the code is correct
9189c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        //   there too.
9199c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        //
9209c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // However, the content of the framebuffer cannot be trusted when
9219c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // we switch to/from FB/OVERLAY, in which case we need to
9229c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // expand the dirty region to those areas too.
9239c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        //
9249c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // Note also that there is a special case when switching from
9259c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // "no layers in FB" to "some layers in FB", where we need to redraw
9269c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // the entire FB, since some areas might contain uninitialized
9279c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // data.
9289c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        //
9299c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // Also we want to make sure to not clear areas that belong to
9303a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian        // layers above that won't redraw (we would just be erasing them),
9319c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // that is, we can't erase anything outside the dirty region.
932a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
9339c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        Region transparent;
934f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian
9359c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        if (!fbLayerCount && hwc.getLayerCount(HWC_FRAMEBUFFER)) {
9369c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian            transparent.set(hw.getBounds());
9379c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian            dirtyInOut = transparent;
9389c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        } else {
9399c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian            for (size_t i=0 ; i<count ; i++) {
9409c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                const sp<LayerBase>& layer(layers[i]);
9419c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                if ((cur[i].hints & HWC_HINT_CLEAR_FB) && layer->isOpaque()) {
9429c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                    transparent.orSelf(layer->visibleRegionScreen);
9439c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                }
9449c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                bool isOverlay = (cur[i].compositionType != HWC_FRAMEBUFFER);
9459c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                if (isOverlay != layer->isOverlay()) {
9469c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                    // we transitioned to/from overlay, so add this layer
9479c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                    // to the dirty region so the framebuffer can be either
9489c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                    // cleared or redrawn.
9499c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                    dirtyInOut.orSelf(layer->visibleRegionScreen);
9509c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                }
9519c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                layer->setOverlay(isOverlay);
952f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian            }
9539c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian            // don't erase stuff outside the dirty region
9549c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian            transparent.andSelf(dirtyInOut);
955f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        }
956f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian
957f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        /*
958f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian         *  clear the area of the FB that need to be transparent
959f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian         */
960f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        if (!transparent.isEmpty()) {
961f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian            glClearColor(0,0,0,0);
962f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian            Region::const_iterator it = transparent.begin();
963f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian            Region::const_iterator const end = transparent.end();
964f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian            const int32_t height = hw.getHeight();
965f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian            while (it != end) {
966f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian                const Rect& r(*it++);
967f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian                const GLint sy = height - (r.top + r.height());
968f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian                glScissor(r.left, sy, r.width(), r.height());
969f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian                glClear(GL_COLOR_BUFFER_BIT);
970f20a32415d055336bc6016fa2de36d126db32746Mathias Agopian            }
971a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        }
972a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
973f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian}
974f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian
975f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopianvoid SurfaceFlinger::composeSurfaces(const Region& dirty)
976f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian{
977cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
978cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian    HWComposer& hwc(hw.getHwComposer());
979cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian
980cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian    const size_t fbLayerCount = hwc.getLayerCount(HWC_FRAMEBUFFER);
98199ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten    if (CC_UNLIKELY(fbLayerCount && !mWormholeRegion.isEmpty())) {
982f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        // should never happen unless the window manager has a bug
983f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        // draw something...
984f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        drawWormhole();
985f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    }
98645721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian
98745721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    /*
98845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     * and then, render the layers targeted at the framebuffer
98945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     */
9904b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian
991cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian    hwc_layer_t* const cur(hwc.getLayers());
992f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
993f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    size_t count = layers.size();
9944b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian
9954b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian
9964b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian    // FIXME: workaround for b/6020860
9974b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian    if (hw.getFlags() & DisplayHardware::BUFFER_PRESERVED) {
9984b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian        for (size_t i=0 ; i<count ; i++) {
9994b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian            if (cur && (cur[i].compositionType == HWC_FRAMEBUFFER)) {
10004b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian                glEnable(GL_SCISSOR_TEST);
10014b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian                glScissor(0,0,0,0);
10024b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian                glClear(GL_COLOR_BUFFER_BIT);
10034b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian                break;
10044b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian            }
10054b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian        }
10064b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian    }
10074b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian    // FIXME: bug6020860 for b/6020860
10084b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian
10094b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian
101045721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
10119c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        if (cur && (cur[i].compositionType != HWC_FRAMEBUFFER)) {
1012f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian            continue;
101345721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        }
101445721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
101545721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        const Region clip(dirty.intersect(layer->visibleRegionScreen));
101645721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        if (!clip.isEmpty()) {
101745721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            layer->draw(clip);
101845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        }
101945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    }
1020edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1021edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1022edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::debugFlashRegions()
1023edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
10240a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
10250a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    const uint32_t flags = hw.getFlags();
102653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian    const int32_t height = hw.getHeight();
10270656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian    if (mSwapRegion.isEmpty()) {
102853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian        return;
102953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian    }
10300a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
10310a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    if (!((flags & DisplayHardware::SWAP_RECTANGLE) ||
10320a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian            (flags & DisplayHardware::BUFFER_PRESERVED))) {
10330a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        const Region repaint((flags & DisplayHardware::PARTIAL_UPDATES) ?
10340a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian                mDirtyRegion.bounds() : hw.bounds());
10350a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        composeSurfaces(repaint);
10360a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    }
10370a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
1038c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_EXTERNAL_OES);
1039c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_2D);
1040edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_BLEND);
1041edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_SCISSOR_TEST);
1042edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
10430926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    static int toggle = 0;
10440926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    toggle = 1 - toggle;
10450926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    if (toggle) {
10460a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        glColor4f(1, 0, 1, 1);
10470926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    } else {
10480a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        glColor4f(1, 1, 0, 1);
10490926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    }
1050edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
105120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    Region::const_iterator it = mDirtyRegion.begin();
105220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    Region::const_iterator const end = mDirtyRegion.end();
105320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    while (it != end) {
105420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        const Rect& r = *it++;
1055edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLfloat vertices[][2] = {
105653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.left,  height - r.top },
105753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.left,  height - r.bottom },
105853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.right, height - r.bottom },
105953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.right, height - r.top }
1060edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        };
1061edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glVertexPointer(2, GL_FLOAT, 0, vertices);
1062edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1063edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
10640a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
10650656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian    hw.flip(mSwapRegion);
1066edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1067edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mDebugRegion > 1)
10680a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        usleep(mDebugRegion * 1000);
1069edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1070edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glEnable(GL_SCISSOR_TEST);
1071edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1072edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1073edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::drawWormhole() const
1074edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1075edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Region region(mWormholeRegion.intersect(mDirtyRegion));
1076edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (region.isEmpty())
1077edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1078edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1079edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw(graphicPlane(0).displayHardware());
1080edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int32_t width = hw.getWidth();
1081edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int32_t height = hw.getHeight();
1082edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
108399ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten    if (CC_LIKELY(!mDebugBackground)) {
10840a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        glClearColor(0,0,0,0);
108520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        Region::const_iterator it = region.begin();
108620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        Region::const_iterator const end = region.end();
108720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        while (it != end) {
108820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            const Rect& r = *it++;
1089edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const GLint sy = height - (r.top + r.height());
1090edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glScissor(r.left, sy, r.width(), r.height());
1091edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glClear(GL_COLOR_BUFFER_BIT);
1092edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1093edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
1094edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GLshort vertices[][2] = { { 0, 0 }, { width, 0 },
1095edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                { width, height }, { 0, height }  };
1096edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GLshort tcoords[][2] = { { 0, 0 }, { 1, 0 },  { 1, 1 }, { 0, 1 } };
1097c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian
1098edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glVertexPointer(2, GL_SHORT, 0, vertices);
1099edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glTexCoordPointer(2, GL_SHORT, 0, tcoords);
1100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
1101c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian
1102c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian        glDisable(GL_TEXTURE_EXTERNAL_OES);
1103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glEnable(GL_TEXTURE_2D);
1104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glBindTexture(GL_TEXTURE_2D, mWormholeTexName);
1105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glMatrixMode(GL_TEXTURE);
1107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glLoadIdentity();
1108c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian
1109c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian        glDisable(GL_BLEND);
1110c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian
1111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glScalef(width*(1.0f/32.0f), height*(1.0f/32.0f), 1);
111220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        Region::const_iterator it = region.begin();
111320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        Region::const_iterator const end = region.end();
111420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        while (it != end) {
111520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            const Rect& r = *it++;
1116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const GLint sy = height - (r.top + r.height());
1117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glScissor(r.left, sy, r.width(), r.height());
1118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1121a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        glDisable(GL_TEXTURE_2D);
1122ebeb7095961e09f5cff0c7cf2c04fa4770b2e033Mathias Agopian        glLoadIdentity();
1123ebeb7095961e09f5cff0c7cf2c04fa4770b2e033Mathias Agopian        glMatrixMode(GL_MODELVIEW);
1124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1125edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1126edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1127076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::addLayer(const sp<LayerBase>& layer)
1128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
1130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    addLayer_l(layer);
1131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
1132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1135076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::addLayer_l(const sp<LayerBase>& layer)
1136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1137f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian    ssize_t i = mCurrentState.layersSortedByZ.add(layer);
11381b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    return (i < 0) ? status_t(i) : status_t(NO_ERROR);
11391b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian}
11401b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
114196f0819f81293076e652792794a961543e6750d7Mathias Agopianssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
114296f0819f81293076e652792794a961543e6750d7Mathias Agopian        const sp<LayerBaseClient>& lbc)
11431b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
114496f0819f81293076e652792794a961543e6750d7Mathias Agopian    // attach this layer to the client
11454f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    size_t name = client->attachLayer(lbc);
11464f113740180b6512b43723c4728f262882dc9b45Mathias Agopian
11474f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    Mutex::Autolock _l(mStateLock);
114896f0819f81293076e652792794a961543e6750d7Mathias Agopian
114996f0819f81293076e652792794a961543e6750d7Mathias Agopian    // add this layer to the current state list
115096f0819f81293076e652792794a961543e6750d7Mathias Agopian    addLayer_l(lbc);
115196f0819f81293076e652792794a961543e6750d7Mathias Agopian
11524f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    return ssize_t(name);
115396f0819f81293076e652792794a961543e6750d7Mathias Agopian}
115496f0819f81293076e652792794a961543e6750d7Mathias Agopian
115596f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer)
115696f0819f81293076e652792794a961543e6750d7Mathias Agopian{
115796f0819f81293076e652792794a961543e6750d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
115896f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = purgatorizeLayer_l(layer);
115996f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR)
116096f0819f81293076e652792794a961543e6750d7Mathias Agopian        setTransactionFlags(eTransactionNeeded);
116196f0819f81293076e652792794a961543e6750d7Mathias Agopian    return err;
1162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1164076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase)
1165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1166b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<LayerBaseClient> lbc(layerBase->getLayerBaseClient());
1167b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (lbc != 0) {
11680d1561275e80073807ac04728951782d943f8882Mathias Agopian        mLayerMap.removeItem( lbc->getSurfaceBinder() );
1169b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    }
1170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase);
1171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (index >= 0) {
1172076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved = true;
1173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
1174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
11753d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    return status_t(index);
1176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
11789a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase)
11799a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
118076cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    // First add the layer to the purgatory list, which makes sure it won't
118176cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    // go away, then remove it from the main list (through a transaction).
11829a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    ssize_t err = removeLayer_l(layerBase);
118376cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    if (err >= 0) {
118476cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian        mLayerPurgatory.add(layerBase);
118576cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    }
11868c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian
11872f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall    mLayersPendingRemoval.push(layerBase);
11880b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian
11893d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // it's possible that we don't find a layer, because it might
11903d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // have been destroyed already -- this is not technically an error
119196f0819f81293076e652792794a961543e6750d7Mathias Agopian    // from the user because there is a race between Client::destroySurface(),
119296f0819f81293076e652792794a961543e6750d7Mathias Agopian    // ~Client() and ~ISurface().
11939a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err;
11949a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
11959a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
119696f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::invalidateLayerVisibility(const sp<LayerBase>& layer)
1197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
119896f0819f81293076e652792794a961543e6750d7Mathias Agopian    layer->forceVisibilityTransaction();
119996f0819f81293076e652792794a961543e6750d7Mathias Agopian    setTransactionFlags(eTraversalNeeded);
120096f0819f81293076e652792794a961543e6750d7Mathias Agopian    return NO_ERROR;
1201edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1202edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1203dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopianuint32_t SurfaceFlinger::peekTransactionFlags(uint32_t flags)
1204dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian{
1205dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian    return android_atomic_release_load(&mTransactionFlags);
1206dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian}
1207dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian
1208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags)
1209edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1210edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return android_atomic_and(~flags, &mTransactionFlags) & flags;
1211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1213bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags)
1214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t old = android_atomic_or(flags, &mTransactionFlags);
1216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((old & flags)==0) { // wake the server up
121799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        signalTransaction();
1218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return old;
1220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1223b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennisvoid SurfaceFlinger::setTransactionState(const Vector<ComposerState>& state,
122428378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        int orientation, uint32_t flags) {
1225698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
1226cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
122728378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    uint32_t transactionFlags = 0;
1228b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis    if (mCurrentState.orientation != orientation) {
1229b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis        if (uint32_t(orientation)<=eOrientation270 || orientation==42) {
1230b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis            mCurrentState.orientation = orientation;
123128378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis            transactionFlags |= eTransactionNeeded;
1232b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis        } else if (orientation != eOrientationUnchanged) {
123332397c1cd3327905173b36baa6fd1c579bc328ffSteve Block            ALOGW("setTransactionState: ignoring unrecognized orientation: %d",
1234b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis                    orientation);
1235b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis        }
1236b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis    }
1237b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis
1238698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    const size_t count = state.size();
1239698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
1240698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const ComposerState& s(state[i]);
1241698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        sp<Client> client( static_cast<Client *>(s.client.get()) );
124228378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        transactionFlags |= setClientStateLocked(client, s.state);
1243698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    }
1244386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian
124528378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    if (transactionFlags) {
1246386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // this triggers the transaction
124728378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        setTransactionFlags(transactionFlags);
1248698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian
1249386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // if this is a synchronous transaction, wait for it to take effect
1250386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // before returning.
1251386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        if (flags & eSynchronous) {
1252386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            mTransationPending = true;
1253386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        }
1254386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        while (mTransationPending) {
1255386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
1256386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            if (CC_UNLIKELY(err != NO_ERROR)) {
1257386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                // just in case something goes wrong in SF, return to the
1258386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                // called after a few seconds.
125932397c1cd3327905173b36baa6fd1c579bc328ffSteve Block                ALOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!");
1260386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                mTransationPending = false;
1261386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                break;
1262386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            }
1263cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        }
1264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1265edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1266edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
12670ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopiansp<ISurface> SurfaceFlinger::createSurface(
12680ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        ISurfaceComposerClient::surface_data_t* params,
12690ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const String8& name,
12700ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const sp<Client>& client,
1271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        DisplayID d, uint32_t w, uint32_t h, PixelFormat format,
1272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t flags)
1273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1274076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBaseClient> layer;
1275a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    sp<ISurface> surfaceHandle;
12766e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian
12776e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    if (int32_t(w|h) < 0) {
1278e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE("createSurface() failed, w or h is negative (w=%d, h=%d)",
12796e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian                int(w), int(h));
12806e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian        return surfaceHandle;
12816e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    }
12828b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
1283ff615cc7a1cceedd705b0623b058c54669b29596Mathias Agopian    //ALOGD("createSurface for (%d x %d), name=%s", w, h, name.string());
1284b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<Layer> normalLayer;
1285edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (flags & eFXSurfaceMask) {
1286edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceNormal:
1287a5529c8778c2f407f482fc12165aeb76c0f505c2Mathias Agopian            normalLayer = createNormalSurface(client, d, w, h, flags, format);
1288a5529c8778c2f407f482fc12165aeb76c0f505c2Mathias Agopian            layer = normalLayer;
1289edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
1290edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceBlur:
12911293a8eb567fd63c072a6970fa9dcf37d076059fMathias Agopian            // for now we treat Blur as Dim, until we can implement it
12921293a8eb567fd63c072a6970fa9dcf37d076059fMathias Agopian            // efficiently.
1293edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceDim:
129496f0819f81293076e652792794a961543e6750d7Mathias Agopian            layer = createDimSurface(client, d, w, h, flags);
1295edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
1296118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        case eFXSurfaceScreenshot:
1297118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian            layer = createScreenshotSurface(client, d, w, h, flags);
1298118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian            break;
1299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1301076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (layer != 0) {
130296f0819f81293076e652792794a961543e6750d7Mathias Agopian        layer->initStates(w, h, flags);
1303285dbde2e0cd0057be070ded3be8f5f453147edcMathias Agopian        layer->setName(name);
130496f0819f81293076e652792794a961543e6750d7Mathias Agopian        ssize_t token = addClientLayer(client, layer);
1305b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        surfaceHandle = layer->getSurface();
13078b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber        if (surfaceHandle != 0) {
130896f0819f81293076e652792794a961543e6750d7Mathias Agopian            params->token = token;
1309a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            params->identity = layer->getIdentity();
1310b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            if (normalLayer != 0) {
1311b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian                Mutex::Autolock _l(mStateLock);
1312a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                mLayerMap.add(layer->getSurfaceBinder(), normalLayer);
1313b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            }
13141c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        }
1315b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
131696f0819f81293076e652792794a961543e6750d7Mathias Agopian        setTransactionFlags(eTransactionNeeded);
1317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return surfaceHandle;
1320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1322b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<Layer> SurfaceFlinger::createNormalSurface(
1323f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        const sp<Client>& client, DisplayID display,
132496f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags,
13251c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        PixelFormat& format)
1326edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1327edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize the surfaces
1328edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (format) { // TODO: take h/w into account
1329edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSPARENT:
1330edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSLUCENT:
1331edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        format = PIXEL_FORMAT_RGBA_8888;
1332edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_OPAQUE:
1334a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888
1335a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian        format = PIXEL_FORMAT_RGB_565;
1336a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#else
13378f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian        format = PIXEL_FORMAT_RGBX_8888;
1338a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif
1339edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1340edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1341edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1342a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888
1343a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian    if (format == PIXEL_FORMAT_RGBX_8888)
1344a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian        format = PIXEL_FORMAT_RGBA_8888;
1345a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif
1346a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian
134796f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<Layer> layer = new Layer(this, display, client);
1348f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian    status_t err = layer->setBuffers(w, h, format, flags);
134999ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten    if (CC_LIKELY(err != NO_ERROR)) {
1350e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE("createNormalSurfaceLocked() failed (%s)", strerror(-err));
1351076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        layer.clear();
1352edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1353edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1354edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1355edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1356b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<LayerDim> SurfaceFlinger::createDimSurface(
1357f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        const sp<Client>& client, DisplayID display,
135896f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags)
1359edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
136096f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<LayerDim> layer = new LayerDim(this, display, client);
1361118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    return layer;
1362118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
1363118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
1364118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopiansp<LayerScreenshot> SurfaceFlinger::createScreenshotSurface(
1365118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        const sp<Client>& client, DisplayID display,
1366118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags)
1367118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{
1368118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    sp<LayerScreenshot> layer = new LayerScreenshot(this, display, client);
1369edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1370edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1371edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
137296f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeSurface(const sp<Client>& client, SurfaceID sid)
13739a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
13749a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    /*
13759a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     * called by the window manager, when a surface should be marked for
13769a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     * destruction.
13778b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber     *
13780aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * The surface is removed from the current and drawing lists, but placed
13790aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * in the purgatory queue, so it's not destroyed right-away (we need
13800aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * to wait for all client's references to go away first).
13819a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     */
13829a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
138348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    status_t err = NAME_NOT_FOUND;
13840aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian    Mutex::Autolock _l(mStateLock);
138596f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<LayerBaseClient> layer = client->getLayerUser(sid);
1386b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam
138748d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    if (layer != 0) {
138848d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        err = purgatorizeLayer_l(layer);
138948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        if (err == NO_ERROR) {
139048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian            setTransactionFlags(eTransactionNeeded);
139148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        }
13929a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    }
13939a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return err;
13949a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
13959a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
1396ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopianstatus_t SurfaceFlinger::destroySurface(const wp<LayerBaseClient>& layer)
1397edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1398759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian    // called by ~ISurface() when all references are gone
1399ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    status_t err = NO_ERROR;
1400ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    sp<LayerBaseClient> l(layer.promote());
1401ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    if (l != NULL) {
1402ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        Mutex::Autolock _l(mStateLock);
1403ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        err = removeLayer_l(l);
1404ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        if (err == NAME_NOT_FOUND) {
1405ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // The surface wasn't in the current list, which means it was
1406ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // removed already, which means it is in the purgatory,
1407ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // and need to be removed from there.
1408ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            ssize_t idx = mLayerPurgatory.remove(l);
1409e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block            ALOGE_IF(idx < 0,
1410ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian                    "layer=%p is not in the purgatory list", l.get());
1411f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        }
1412e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE_IF(err<0 && err != NAME_NOT_FOUND,
1413ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian                "error removing layer=%p (%s)", l.get(), strerror(-err));
1414ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    }
1415ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    return err;
1416edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1417edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1418698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopianuint32_t SurfaceFlinger::setClientStateLocked(
141996f0819f81293076e652792794a961543e6750d7Mathias Agopian        const sp<Client>& client,
1420698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const layer_state_t& s)
1421edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1422edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t flags = 0;
1423698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    sp<LayerBaseClient> layer(client->getLayerUser(s.surface));
1424698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    if (layer != 0) {
1425698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const uint32_t what = s.what;
1426698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & ePositionChanged) {
1427698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setPosition(s.x, s.y))
1428698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1429698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1430698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eLayerChanged) {
1431698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
1432698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setLayer(s.z)) {
1433698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                mCurrentState.layersSortedByZ.removeAt(idx);
1434698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                mCurrentState.layersSortedByZ.add(layer);
1435698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                // we need traversal (state changed)
1436698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                // AND transaction (list changed)
1437698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTransactionNeeded|eTraversalNeeded;
1438edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1439698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1440698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eSizeChanged) {
1441698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setSize(s.w, s.h)) {
1442698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1443edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1444edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1445698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eAlphaChanged) {
1446698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f)))
1447698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1448698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1449698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eMatrixChanged) {
1450698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setMatrix(s.matrix))
1451698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1452698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1453698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eTransparentRegionChanged) {
1454698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setTransparentRegionHint(s.transparentRegion))
1455698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1456698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1457698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eVisibilityChanged) {
1458698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setFlags(s.flags, s.mask))
1459698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1460698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1461edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1462698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    return flags;
1463edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1464edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1465b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// ---------------------------------------------------------------------------
1466b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
1467b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopianvoid SurfaceFlinger::onScreenAcquired() {
1468b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
1469b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    hw.acquireScreen();
147022ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian    mEventThread->onScreenAcquired();
1471b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    // this is a temporary work-around, eventually this should be called
1472b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    // by the power-manager
1473b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    SurfaceFlinger::turnElectronBeamOn(mElectronBeamAnimationMode);
1474b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    mDirtyRegion.set(hw.bounds());
147522ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian    // from this point on, SF will process updates again
1476edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1477edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1478b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopianvoid SurfaceFlinger::onScreenReleased() {
1479b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
1480b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    if (hw.isScreenAcquired()) {
148122ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian        mEventThread->onScreenReleased();
1482b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        mDirtyRegion.set(hw.bounds());
1483b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        hw.releaseScreen();
1484b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        // from this point on, SF will stop drawing
1485b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    }
1486b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian}
1487b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
1488b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopianvoid SurfaceFlinger::screenAcquired() {
1489b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    class MessageScreenAcquired : public MessageBase {
1490b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        SurfaceFlinger* flinger;
1491b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    public:
1492b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        MessageScreenAcquired(SurfaceFlinger* flinger) : flinger(flinger) { }
1493b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        virtual bool handler() {
1494b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            flinger->onScreenAcquired();
1495b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            return true;
1496b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        }
1497b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    };
1498b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    sp<MessageBase> msg = new MessageScreenAcquired(this);
1499b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    postMessageSync(msg);
1500edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1501edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1502b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopianvoid SurfaceFlinger::screenReleased() {
1503b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    class MessageScreenReleased : public MessageBase {
1504b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        SurfaceFlinger* flinger;
1505b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    public:
1506b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        MessageScreenReleased(SurfaceFlinger* flinger) : flinger(flinger) { }
1507b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        virtual bool handler() {
1508b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            flinger->onScreenReleased();
1509b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            return true;
1510b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        }
1511b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    };
1512b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    sp<MessageBase> msg = new MessageScreenReleased(this);
1513b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    postMessageSync(msg);
1514b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian}
1515b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
1516b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// ---------------------------------------------------------------------------
1517b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
1518edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
1519edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
15201d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling    const size_t SIZE = 4096;
1521edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char buffer[SIZE];
1522edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    String8 result;
152399b49840d309727678b77403d6cc9f920111623fMathias Agopian
152499b49840d309727678b77403d6cc9f920111623fMathias Agopian    if (!PermissionCache::checkCallingPermission(sDump)) {
1525edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        snprintf(buffer, SIZE, "Permission Denial: "
1526edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                "can't dump SurfaceFlinger from pid=%d, uid=%d\n",
1527edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                IPCThreadState::self()->getCallingPid(),
1528edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                IPCThreadState::self()->getCallingUid());
1529edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        result.append(buffer);
1530edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
15319795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // Try to get the main lock, but don't insist if we can't
15329795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // (this would indicate SF is stuck, but we want to be able to
15339795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // print something in dumpsys).
15349795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        int retry = 3;
15359795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        while (mStateLock.tryLock()<0 && --retry>=0) {
15369795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            usleep(1000000);
15379795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
15389795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const bool locked(retry >= 0);
15399795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (!locked) {
15408b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber            snprintf(buffer, SIZE,
15419795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "SurfaceFlinger appears to be unresponsive, "
15429795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "dumping anyways (no locks held)\n");
15439795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            result.append(buffer);
15449795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
15459795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
154682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        bool dumpAll = true;
154782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        size_t index = 0;
154825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        size_t numArgs = args.size();
154925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        if (numArgs) {
155025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
155125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--list"))) {
155225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                index++;
155325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                listLayersLocked(args, index, result, buffer, SIZE);
155435aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
155525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            }
155625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
155725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
155825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--latency"))) {
155982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                index++;
156082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                dumpStatsLocked(args, index, result, buffer, SIZE);
156135aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
156282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            }
156325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
156425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
156525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--latency-clear"))) {
156625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                index++;
156725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                clearStatsLocked(args, index, result, buffer, SIZE);
156835aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
156925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            }
1570edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
15711b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
157282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (dumpAll) {
157382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            dumpAllLocked(result, buffer, SIZE);
157482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
157548b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
157682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (locked) {
157782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mStateLock.unlock();
157848b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        }
157982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
158082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    write(fd, result.string(), result.size());
158182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    return NO_ERROR;
158282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
158348b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
158425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::listLayersLocked(const Vector<String16>& args, size_t& index,
158525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        String8& result, char* buffer, size_t SIZE) const
158625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
158725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
158825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const size_t count = currentLayers.size();
158925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
159025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
159125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        snprintf(buffer, SIZE, "%s\n", layer->getName().string());
159225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        result.append(buffer);
159325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
159425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
159525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
159682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index,
159782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        String8& result, char* buffer, size_t SIZE) const
159882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
159982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    String8 name;
160082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    if (index < args.size()) {
160182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        name = String8(args[index]);
160282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        index++;
160382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
160448b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
160582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
160682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const size_t count = currentLayers.size();
160782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    for (size_t i=0 ; i<count ; i++) {
160882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
160982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (name.isEmpty()) {
161082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            snprintf(buffer, SIZE, "%s\n", layer->getName().string());
161182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            result.append(buffer);
161282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
161382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (name.isEmpty() || (name == layer->getName())) {
161482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            layer->dumpStats(result, buffer, SIZE);
161582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
161682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
161782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
1618ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian
161925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& index,
162025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        String8& result, char* buffer, size_t SIZE) const
162125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
162225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    String8 name;
162325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    if (index < args.size()) {
162425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        name = String8(args[index]);
162525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        index++;
162625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
162725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
162825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
162925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const size_t count = currentLayers.size();
163025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
163125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
163225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        if (name.isEmpty() || (name == layer->getName())) {
163325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            layer->clearStats();
163425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        }
163525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
163625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
163725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
163882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpAllLocked(
163982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        String8& result, char* buffer, size_t SIZE) const
164082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
164182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    // figure out if we're stuck somewhere
164282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t now = systemTime();
164382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t inSwapBuffers(mDebugInSwapBuffers);
164482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t inTransaction(mDebugInTransaction);
164582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0;
164682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0;
1647bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
164882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
164982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump the visible layer list
165082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
165182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
165282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const size_t count = currentLayers.size();
165382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "Visible layers (count = %d)\n", count);
165482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
165582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    for (size_t i=0 ; i<count ; i++) {
165682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
165782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        layer->dump(result, buffer, SIZE);
165882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
1659bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
166082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
166182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump the layers in the purgatory
166282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
1663ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian
166482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const size_t purgatorySize = mLayerPurgatory.size();
166582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "Purgatory state (%d entries)\n", purgatorySize);
166682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
166782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    for (size_t i=0 ; i<purgatorySize ; i++) {
166882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
166982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        layer->shortDump(result, buffer, SIZE);
167082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
16711b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
167282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
167382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump SurfaceFlinger global state
167482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
16751b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
167682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "SurfaceFlinger global state:\n");
167782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
16781b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
167982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const GLExtensions& extensions(GLExtensions::getInstance());
168082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "GLES: %s, %s, %s\n",
168182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            extensions.getVendor(),
168282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            extensions.getRenderer(),
168382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            extensions.getVersion());
168482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
1685d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
168682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "EGL : %s\n",
168782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            eglQueryString(graphicPlane(0).getEGLDisplay(),
168882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                    EGL_VERSION_HW_ANDROID));
168982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
169073d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian
169182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "EXTS: %s\n", extensions.getExtension());
169282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
16939795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
169482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    mWormholeRegion.dump(result, "WormholeRegion");
169582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
169682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE,
169782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  orientation=%d, canDraw=%d\n",
169882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mCurrentState.orientation, hw.canDraw());
169982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
170082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE,
170182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  last eglSwapBuffers() time: %f us\n"
170282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  last transaction time     : %f us\n"
1703c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian            "  transaction-flags         : %08x\n"
170482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  refresh-rate              : %f fps\n"
170582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  x-dpi                     : %f\n"
1706b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian            "  y-dpi                     : %f\n"
1707b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian            "  density                   : %f\n",
170882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mLastSwapBufferTime/1000.0,
170982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mLastTransactionTime/1000.0,
1710c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian            mTransactionFlags,
171182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            hw.getRefreshRate(),
171282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            hw.getDpiX(),
1713b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian            hw.getDpiY(),
1714b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian            hw.getDensity());
171582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
171682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
171782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "  eglSwapBuffers time: %f us\n",
171882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            inSwapBuffersDuration/1000.0);
171982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
172082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
172182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "  transaction time: %f us\n",
172282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            inTransactionDuration/1000.0);
172382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
172482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
172582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
172682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * VSYNC state
172782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
172882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    mEventThread->dump(result, buffer, SIZE);
172982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
173082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
173182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump HWComposer state
173282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
173382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    HWComposer& hwc(hw.getHwComposer());
173482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "h/w composer state:\n");
173582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
173682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "  h/w composer %s and %s\n",
173782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            hwc.initCheck()==NO_ERROR ? "present" : "not present",
173882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                    (mDebugDisableHWC || mDebugRegion) ? "disabled" : "enabled");
173982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
174082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    hwc.dump(result, buffer, SIZE, mVisibleLayersSortedByZ);
174182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
174282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
174382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump gralloc state
174482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
174582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
174682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    alloc.dump(result);
174782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    hw.dump(result);
1748edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1749edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1750edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::onTransact(
1751edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
1752edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1753edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (code) {
1754edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case CREATE_CONNECTION:
1755698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        case SET_TRANSACTION_STATE:
1756edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case SET_ORIENTATION:
1757edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case BOOT_FINISHED:
175859119e658a12279e8fff508f8773843de2d90917Mathias Agopian        case TURN_ELECTRON_BEAM_OFF:
17599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        case TURN_ELECTRON_BEAM_ON:
1760edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        {
1761edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // codes that require permission check
1762edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            IPCThreadState* ipc = IPCThreadState::self();
1763edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int pid = ipc->getCallingPid();
1764a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian            const int uid = ipc->getCallingUid();
176599b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
176699b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) {
1767e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block                ALOGE("Permission Denial: "
1768375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                        "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
1769375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                return PERMISSION_DENIED;
1770edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
17711b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
17721b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
17731b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        case CAPTURE_SCREEN:
17741b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
17751b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            // codes that require permission check
17761b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
17771b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int pid = ipc->getCallingPid();
17781b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int uid = ipc->getCallingUid();
177999b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
178099b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) {
1781e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block                ALOGE("Permission Denial: "
17821b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                        "can't read framebuffer pid=%d, uid=%d", pid, uid);
17831b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                return PERMISSION_DENIED;
17841b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            }
17851b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
1786edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1787edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
17881b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
1789edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
1790edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
1791b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        CHECK_INTERFACE(ISurfaceComposer, data, reply);
179299ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten        if (CC_UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) {
1793375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
1794375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int pid = ipc->getCallingPid();
1795375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int uid = ipc->getCallingUid();
1796e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block            ALOGE("Permission Denial: "
1797375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                    "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
1798edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return PERMISSION_DENIED;
1799edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1800edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int n;
1801edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        switch (code) {
180201b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian            case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE
180335b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian            case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE
1804edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1805edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1002:  // SHOW_UPDATES
1806edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                n = data.readInt32();
1807edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDebugRegion = n ? n : (mDebugRegion ? 0 : 1);
180853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
180953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
1810edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1811edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1003:  // SHOW_BACKGROUND
1812edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                n = data.readInt32();
1813edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDebugBackground = n ? 1 : 0;
1814edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1815edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1004:{ // repaint everything
181653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
1817cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
1818cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            }
1819cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            case 1005:{ // force transaction
1820cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
1821cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
1822edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
18234d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            case 1006:{ // send empty update
18244d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian                signalRefresh();
18254d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian                return NO_ERROR;
18264d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            }
182753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian            case 1008:  // toggle use of hw composer
182853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                n = data.readInt32();
182953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                mDebugDisableHWC = n ? 1 : 0;
183053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
183153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
183253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                return NO_ERROR;
1833a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian            case 1009:  // toggle use of transform hint
1834a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                n = data.readInt32();
1835a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                mDebugDisableTransformHint = n ? 1 : 0;
1836a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                invalidateHwcGeometry();
1837a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                repaintEverything();
1838a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                return NO_ERROR;
1839edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1010:  // interrogate.
184001b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian                reply->writeInt32(0);
1841edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(0);
1842edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(mDebugRegion);
1843edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(mDebugBackground);
184412839bee29bdcc65731b4d42029cc59e2320c5c4Dianne Hackborn                reply->writeInt32(mDebugDisableHWC);
1845edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1846edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1013: {
1847edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                Mutex::Autolock _l(mStateLock);
1848edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                const DisplayHardware& hw(graphicPlane(0).displayHardware());
1849edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(hw.getPageFlipCount());
1850edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1851edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return NO_ERROR;
1852edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1853edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1854edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return err;
1855edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1856edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
185753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopianvoid SurfaceFlinger::repaintEverything() {
185853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
18590dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    const Rect bounds(hw.getBounds());
18600dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    setInvalidateRegion(Region(bounds));
186199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    signalTransaction();
186253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian}
186353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian
18640dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopianvoid SurfaceFlinger::setInvalidateRegion(const Region& reg) {
18650dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    Mutex::Autolock _l(mInvalidateLock);
18660dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    mInvalidateRegion = reg;
18670dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian}
18680dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian
18690dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias AgopianRegion SurfaceFlinger::getAndClearInvalidateRegion() {
18700dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    Mutex::Autolock _l(mInvalidateLock);
18710dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    Region reg(mInvalidateRegion);
18720dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    mInvalidateRegion.clear();
18730dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    return reg;
18740dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian}
18750dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian
187659119e658a12279e8fff508f8773843de2d90917Mathias Agopian// ---------------------------------------------------------------------------
187759119e658a12279e8fff508f8773843de2d90917Mathias Agopian
1878118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopianstatus_t SurfaceFlinger::renderScreenToTexture(DisplayID dpy,
1879118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        GLuint* textureName, GLfloat* uOut, GLfloat* vOut)
1880118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{
1881118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    Mutex::Autolock _l(mStateLock);
1882118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    return renderScreenToTextureLocked(dpy, textureName, uOut, vOut);
1883118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
1884118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
18859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::renderScreenToTextureLocked(DisplayID dpy,
18869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        GLuint* textureName, GLfloat* uOut, GLfloat* vOut)
188759119e658a12279e8fff508f8773843de2d90917Mathias Agopian{
188822ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian    ATRACE_CALL();
188922ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian
189059119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
189159119e658a12279e8fff508f8773843de2d90917Mathias Agopian        return INVALID_OPERATION;
189259119e658a12279e8fff508f8773843de2d90917Mathias Agopian
189359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // get screen geometry
189459119e658a12279e8fff508f8773843de2d90917Mathias Agopian    const DisplayHardware& hw(graphicPlane(dpy).displayHardware());
189559119e658a12279e8fff508f8773843de2d90917Mathias Agopian    const uint32_t hw_w = hw.getWidth();
189659119e658a12279e8fff508f8773843de2d90917Mathias Agopian    const uint32_t hw_h = hw.getHeight();
189759119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLfloat u = 1;
189859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLfloat v = 1;
189959119e658a12279e8fff508f8773843de2d90917Mathias Agopian
190059119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // make sure to clear all GL error flags
190159119e658a12279e8fff508f8773843de2d90917Mathias Agopian    while ( glGetError() != GL_NO_ERROR ) ;
190259119e658a12279e8fff508f8773843de2d90917Mathias Agopian
190359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // create a FBO
190459119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLuint name, tname;
190559119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glGenTextures(1, &tname);
190659119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
19079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
19089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            hw_w, hw_h, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
190959119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (glGetError() != GL_NO_ERROR) {
1910015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian        while ( glGetError() != GL_NO_ERROR ) ;
191159119e658a12279e8fff508f8773843de2d90917Mathias Agopian        GLint tw = (2 << (31 - clz(hw_w)));
191259119e658a12279e8fff508f8773843de2d90917Mathias Agopian        GLint th = (2 << (31 - clz(hw_h)));
19139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
19149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian                tw, th, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
191559119e658a12279e8fff508f8773843de2d90917Mathias Agopian        u = GLfloat(hw_w) / tw;
191659119e658a12279e8fff508f8773843de2d90917Mathias Agopian        v = GLfloat(hw_h) / th;
191759119e658a12279e8fff508f8773843de2d90917Mathias Agopian    }
191859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glGenFramebuffersOES(1, &name);
191959119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
19209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES,
19219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0);
192259119e658a12279e8fff508f8773843de2d90917Mathias Agopian
19239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // redraw the screen entirely...
1924c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_EXTERNAL_OES);
1925c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_2D);
192662f7114719d2009dca7dd120f0fe29a24bd77a40Mathias Agopian    glDisable(GL_SCISSOR_TEST);
19279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glClearColor(0,0,0,1);
19289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glClear(GL_COLOR_BUFFER_BIT);
192962f7114719d2009dca7dd120f0fe29a24bd77a40Mathias Agopian    glEnable(GL_SCISSOR_TEST);
1930a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glMatrixMode(GL_MODELVIEW);
1931a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glLoadIdentity();
19329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
19339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const size_t count = layers.size();
19349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (size_t i=0 ; i<count ; ++i) {
19359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
19369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        layer->drawForSreenShot();
19379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
193859119e658a12279e8fff508f8773843de2d90917Mathias Agopian
1939118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    hw.compositionComplete();
1940118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
19419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // back to main framebuffer
19429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
19439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_SCISSOR_TEST);
19449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDeleteFramebuffersOES(1, &name);
194559119e658a12279e8fff508f8773843de2d90917Mathias Agopian
19469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *textureName = tname;
19479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *uOut = u;
19489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *vOut = v;
19499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
19509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
195159119e658a12279e8fff508f8773843de2d90917Mathias Agopian
19529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// ---------------------------------------------------------------------------
195359119e658a12279e8fff508f8773843de2d90917Mathias Agopian
19549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::electronBeamOffAnimationImplLocked()
19559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
19569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // get screen geometry
19579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
19589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_w = hw.getWidth();
19599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_h = hw.getHeight();
1960a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    const Region screenBounds(hw.getBounds());
196159119e658a12279e8fff508f8773843de2d90917Mathias Agopian
19629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat u, v;
19639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLuint tname;
1964118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    status_t result = renderScreenToTextureLocked(0, &tname, &u, &v);
19659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (result != NO_ERROR) {
19669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return result;
19679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
196859119e658a12279e8fff508f8773843de2d90917Mathias Agopian
19699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat vtx[8];
1970a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    const GLfloat texCoords[4][2] = { {0,0}, {0,v}, {u,v}, {u,0} };
19719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
19729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
19739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
19749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1975b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1976b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
19779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
19789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
19799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glVertexPointer(2, GL_FLOAT, 0, vtx);
19809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
1981ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    /*
1982ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     * Texture coordinate mapping
1983ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *
1984ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *                 u
1985ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *    1 +----------+---+
1986ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |     |    |   |  image is inverted
1987ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |     V    |   |  w.r.t. the texture
1988ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *  1-v +----------+   |  coordinates
1989ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |              |
1990ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |              |
1991ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |              |
1992ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *    0 +--------------+
1993ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      0              1
1994ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *
1995ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     */
1996ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian
19979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class s_curve_interpolator {
19989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float nbFrames, s, v;
19999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
20009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        s_curve_interpolator(int nbFrames, float s)
20019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : nbFrames(1.0f / (nbFrames-1)), s(s),
20029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian          v(1.0f + expf(-s + 0.5f*s)) {
20039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
20049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float operator()(int f) {
20059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const float x = f * nbFrames;
20069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f;
20079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
20089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
20099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class v_stretch {
20119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
20129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
20139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        v_stretch(uint32_t hw_w, uint32_t hw_h)
20149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
20159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
20169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
20179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w + (hw_w * v);
20189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = hw_h - (hw_h * v);
20199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
20209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
2021ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[0] = x;         vtx[1] = y;
2022ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
2023ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
2024ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
20259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
20269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
20279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class h_stretch {
20299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
20309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
20319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        h_stretch(uint32_t hw_w, uint32_t hw_h)
20329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
203359119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
20349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
20359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w - (hw_w * v);
20369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = 1.0f;
20379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
20389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
2039ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[0] = x;         vtx[1] = y;
2040ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
2041ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
2042ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
20439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
20449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
20459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // the full animation is 24 frames
2047ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    char value[PROPERTY_VALUE_MAX];
2048ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    property_get("debug.sf.electron_frames", value, "24");
2049ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    int nbFrames = (atoi(value) + 1) >> 1;
2050ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    if (nbFrames <= 0) // just in case
2051ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian        nbFrames = 24;
2052ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian
20539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itr(nbFrames, 7.5f);
20549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itg(nbFrames, 8.0f);
20559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itb(nbFrames, 8.5f);
20569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    v_stretch vverts(hw_w, hw_h);
2058a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian
2059a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glMatrixMode(GL_TEXTURE);
2060a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glLoadIdentity();
2061a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glMatrixMode(GL_MODELVIEW);
2062a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glLoadIdentity();
2063a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian
20649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnable(GL_BLEND);
20659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBlendFunc(GL_ONE, GL_ONE);
20669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=0 ; i<nbFrames ; i++) {
20679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float x, y, w, h;
20689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vr = itr(i);
20699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vg = itg(i);
20709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vb = itb(i);
20719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // clear screen
20739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(1,1,1,1);
20749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
20759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glEnable(GL_TEXTURE_2D);
207659119e658a12279e8fff508f8773843de2d90917Mathias Agopian
20779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the red plane
20789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vr);
20799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(1,0,0,1);
20809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
20819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the green plane
20839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vg);
20849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,1,0,1);
20859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
20869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the blue plane
20889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vb);
20899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,0,1,1);
20909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
20919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the white highlight (we use the last vertices)
209359119e658a12279e8fff508f8773843de2d90917Mathias Agopian        glDisable(GL_TEXTURE_2D);
209459119e658a12279e8fff508f8773843de2d90917Mathias Agopian        glColorMask(1,1,1,1);
20959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColor4f(vg, vg, vg, 1);
20969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
20979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
20989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
20999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    h_stretch hverts(hw_w, hw_h);
21019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_BLEND);
21029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_TEXTURE_2D);
21039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
21049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=0 ; i<nbFrames ; i++) {
21059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float v = itg(i);
21069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hverts(vtx, v);
21079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
21089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColor4f(1-v, 1-v, 1-v, 1);
21099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
21109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
21119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
21129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
21149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnable(GL_SCISSOR_TEST);
21159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
21169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDeleteTextures(1, &tname);
2117a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    glDisable(GL_TEXTURE_2D);
2118c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_BLEND);
21199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
21209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
21219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::electronBeamOnAnimationImplLocked()
21239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
21249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    status_t result = PERMISSION_DENIED;
21259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
21279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return INVALID_OPERATION;
21289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // get screen geometry
21319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
21329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_w = hw.getWidth();
21339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_h = hw.getHeight();
21349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const Region screenBounds(hw.bounds());
21359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat u, v;
21379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLuint tname;
21389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    result = renderScreenToTextureLocked(0, &tname, &u, &v);
21399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (result != NO_ERROR) {
21409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return result;
21419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
21429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat vtx[8];
21449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const GLfloat texCoords[4][2] = { {0,v}, {0,0}, {u,0}, {u,v} };
21459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
21469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
21479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
21489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2149b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2150b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
21519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
21529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
21539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glVertexPointer(2, GL_FLOAT, 0, vtx);
21549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class s_curve_interpolator {
21569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float nbFrames, s, v;
21579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
21589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        s_curve_interpolator(int nbFrames, float s)
21599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : nbFrames(1.0f / (nbFrames-1)), s(s),
21609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian          v(1.0f + expf(-s + 0.5f*s)) {
21619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
21629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float operator()(int f) {
21639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const float x = f * nbFrames;
21649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f;
21659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
21669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
21679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class v_stretch {
21699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
21709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
21719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        v_stretch(uint32_t hw_w, uint32_t hw_h)
21729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
217359119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
21749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
21759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w + (hw_w * v);
21769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = hw_h - (hw_h * v);
21779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
21789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
21799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[0] = x;         vtx[1] = y;
21809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
21819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
21829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
21839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
21849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
21859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class h_stretch {
21879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
21889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
21899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        h_stretch(uint32_t hw_w, uint32_t hw_h)
21909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
21919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
21929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
21939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w - (hw_w * v);
21949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = 1.0f;
21959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
21969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
21979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[0] = x;         vtx[1] = y;
21989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
21999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
22009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
22019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
22029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
22039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2204a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian    // the full animation is 12 frames
2205a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian    int nbFrames = 8;
22069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itr(nbFrames, 7.5f);
22079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itg(nbFrames, 8.0f);
22089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itb(nbFrames, 8.5f);
22099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    h_stretch hverts(hw_w, hw_h);
22119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_BLEND);
22129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_TEXTURE_2D);
22139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
22149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=nbFrames-1 ; i>=0 ; i--) {
22159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float v = itg(i);
22169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hverts(vtx, v);
22179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
22189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColor4f(1-v, 1-v, 1-v, 1);
22199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
22209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
22219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
22229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2223a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian    nbFrames = 4;
22249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    v_stretch vverts(hw_w, hw_h);
22259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnable(GL_BLEND);
22269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBlendFunc(GL_ONE, GL_ONE);
22279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=nbFrames-1 ; i>=0 ; i--) {
22289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float x, y, w, h;
22299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vr = itr(i);
22309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vg = itg(i);
22319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vb = itb(i);
223259119e658a12279e8fff508f8773843de2d90917Mathias Agopian
22339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // clear screen
223459119e658a12279e8fff508f8773843de2d90917Mathias Agopian        glColorMask(1,1,1,1);
22359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
22369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glEnable(GL_TEXTURE_2D);
22379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the red plane
22399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vr);
22409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(1,0,0,1);
22419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
22429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the green plane
22449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vg);
22459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,1,0,1);
22469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
22479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the blue plane
22499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vb);
22509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,0,1,1);
22519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
22529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
225459119e658a12279e8fff508f8773843de2d90917Mathias Agopian    }
225559119e658a12279e8fff508f8773843de2d90917Mathias Agopian
22569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
22579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnable(GL_SCISSOR_TEST);
22589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
225959119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glDeleteTextures(1, &tname);
2260a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    glDisable(GL_TEXTURE_2D);
2261c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_BLEND);
226259119e658a12279e8fff508f8773843de2d90917Mathias Agopian
22639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
22649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
22659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// ---------------------------------------------------------------------------
22679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2268abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOffImplLocked(int32_t mode)
22699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
227022ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian    ATRACE_CALL();
227122ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian
22729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    DisplayHardware& hw(graphicPlane(0).editDisplayHardware());
22739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (!hw.canDraw()) {
22749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // we're already off
22759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return NO_ERROR;
22769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
22777ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian
22787ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian    // turn off hwc while we're doing the animation
22797ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian    hw.getHwComposer().disable();
22807ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian    // and make sure to turn it back on (if needed) next time we compose
22817ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian    invalidateHwcGeometry();
22827ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian
2283abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    if (mode & ISurfaceComposer::eElectronBeamAnimationOff) {
2284abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        electronBeamOffAnimationImplLocked();
2285abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    }
2286abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian
2287abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    // always clear the whole screen at the end of the animation
2288abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    glClearColor(0,0,0,1);
2289abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    glDisable(GL_SCISSOR_TEST);
2290abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    glClear(GL_COLOR_BUFFER_BIT);
2291abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    glEnable(GL_SCISSOR_TEST);
2292abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    hw.flip( Region(hw.bounds()) );
2293abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian
2294015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian    return NO_ERROR;
229559119e658a12279e8fff508f8773843de2d90917Mathias Agopian}
229659119e658a12279e8fff508f8773843de2d90917Mathias Agopian
229759119e658a12279e8fff508f8773843de2d90917Mathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOff(int32_t mode)
229859119e658a12279e8fff508f8773843de2d90917Mathias Agopian{
229959119e658a12279e8fff508f8773843de2d90917Mathias Agopian    class MessageTurnElectronBeamOff : public MessageBase {
230059119e658a12279e8fff508f8773843de2d90917Mathias Agopian        SurfaceFlinger* flinger;
2301abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        int32_t mode;
230259119e658a12279e8fff508f8773843de2d90917Mathias Agopian        status_t result;
230359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    public:
2304abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        MessageTurnElectronBeamOff(SurfaceFlinger* flinger, int32_t mode)
2305abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            : flinger(flinger), mode(mode), result(PERMISSION_DENIED) {
230659119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
230759119e658a12279e8fff508f8773843de2d90917Mathias Agopian        status_t getResult() const {
230859119e658a12279e8fff508f8773843de2d90917Mathias Agopian            return result;
230959119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
231059119e658a12279e8fff508f8773843de2d90917Mathias Agopian        virtual bool handler() {
231159119e658a12279e8fff508f8773843de2d90917Mathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
2312abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            result = flinger->turnElectronBeamOffImplLocked(mode);
231359119e658a12279e8fff508f8773843de2d90917Mathias Agopian            return true;
231459119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
231559119e658a12279e8fff508f8773843de2d90917Mathias Agopian    };
231659119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2317abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    sp<MessageBase> msg = new MessageTurnElectronBeamOff(this, mode);
231859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    status_t res = postMessageSync(msg);
231959119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (res == NO_ERROR) {
232059119e658a12279e8fff508f8773843de2d90917Mathias Agopian        res = static_cast<MessageTurnElectronBeamOff*>( msg.get() )->getResult();
23219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
23229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // work-around: when the power-manager calls us we activate the
23239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // animation. eventually, the "on" animation will be called
23249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // by the power-manager itself
2325abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        mElectronBeamAnimationMode = mode;
232659119e658a12279e8fff508f8773843de2d90917Mathias Agopian    }
232759119e658a12279e8fff508f8773843de2d90917Mathias Agopian    return res;
232859119e658a12279e8fff508f8773843de2d90917Mathias Agopian}
232959119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2330edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
2331edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2332abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOnImplLocked(int32_t mode)
23339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
23349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    DisplayHardware& hw(graphicPlane(0).editDisplayHardware());
23359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (hw.canDraw()) {
23369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // we're already on
23379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return NO_ERROR;
23389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
2339abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    if (mode & ISurfaceComposer::eElectronBeamAnimationOn) {
2340abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        electronBeamOnAnimationImplLocked();
2341abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    }
2342a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian
2343a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian    // make sure to redraw the whole screen when the animation is done
2344a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian    mDirtyRegion.set(hw.bounds());
234599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    signalTransaction();
2346a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian
2347015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian    return NO_ERROR;
23489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
23499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
23509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOn(int32_t mode)
23519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
23529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class MessageTurnElectronBeamOn : public MessageBase {
23539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        SurfaceFlinger* flinger;
2354abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        int32_t mode;
23559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        status_t result;
23569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
2357abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        MessageTurnElectronBeamOn(SurfaceFlinger* flinger, int32_t mode)
2358abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            : flinger(flinger), mode(mode), result(PERMISSION_DENIED) {
23599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
23609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        status_t getResult() const {
23619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return result;
23629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
23639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        virtual bool handler() {
23649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
2365abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            result = flinger->turnElectronBeamOnImplLocked(mode);
23669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return true;
23679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
23689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
23699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2370abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    postMessageAsync( new MessageTurnElectronBeamOn(this, mode) );
23719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
23729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
23739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
23749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// ---------------------------------------------------------------------------
23759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
237674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopianstatus_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy,
237774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        sp<IMemoryHeap>* heap,
237874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t* w, uint32_t* h, PixelFormat* f,
2379bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t sw, uint32_t sh,
2380bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ, uint32_t maxLayerZ)
238174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{
2382fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian    ATRACE_CALL();
2383fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian
238474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    status_t result = PERMISSION_DENIED;
238574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
238674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // only one display supported for now
238799ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten    if (CC_UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
238874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return BAD_VALUE;
238974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
239074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
239174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return INVALID_OPERATION;
239274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
239374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // get screen geometry
239474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const DisplayHardware& hw(graphicPlane(dpy).displayHardware());
239574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const uint32_t hw_w = hw.getWidth();
239674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const uint32_t hw_h = hw.getHeight();
239774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
239874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    if ((sw > hw_w) || (sh > hw_h))
239974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return BAD_VALUE;
240074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
240174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    sw = (!sw) ? hw_w : sw;
240274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    sh = (!sh) ? hw_h : sh;
240374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const size_t size = sw * sh * 4;
240474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
24059d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block    //ALOGD("screenshot: sw=%d, sh=%d, minZ=%d, maxZ=%d",
24061c71a47a6db679a3212f0c99e14f330d6da500faMathias Agopian    //        sw, sh, minLayerZ, maxLayerZ);
2407c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
240874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // make sure to clear all GL error flags
240974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    while ( glGetError() != GL_NO_ERROR ) ;
241074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
241174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // create a FBO
241274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    GLuint name, tname;
241374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glGenRenderbuffersOES(1, &tname);
241474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindRenderbufferOES(GL_RENDERBUFFER_OES, tname);
241574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA8_OES, sw, sh);
2416fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian
241774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glGenFramebuffersOES(1, &name);
241874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
241974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES,
242074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, tname);
242174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
242274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
2423c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
242474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    if (status == GL_FRAMEBUFFER_COMPLETE_OES) {
242574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
242674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // invert everything, b/c glReadPixel() below will invert the FB
242774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glViewport(0, 0, sw, sh);
2428f653b897a449e10d6cbfb6e0812f7b0bb02d6482Mathias Agopian        glScissor(0, 0, sw, sh);
2429ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian        glEnable(GL_SCISSOR_TEST);
243074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_PROJECTION);
243174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glPushMatrix();
243274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glLoadIdentity();
2433ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian        glOrthof(0, hw_w, hw_h, 0, 0, 1);
243474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_MODELVIEW);
243574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
243674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // redraw the screen entirely...
243774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glClearColor(0,0,0,1);
243874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
2439f653b897a449e10d6cbfb6e0812f7b0bb02d6482Mathias Agopian
24409575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        const LayerVector& layers(mDrawingState.layersSortedByZ);
24419575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        const size_t count = layers.size();
244274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        for (size_t i=0 ; i<count ; ++i) {
244374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            const sp<LayerBase>& layer(layers[i]);
2444b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian            const uint32_t flags = layer->drawingState().flags;
2445b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian            if (!(flags & ISurfaceComposer::eLayerHidden)) {
2446b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                const uint32_t z = layer->drawingState().z;
2447b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                if (z >= minLayerZ && z <= maxLayerZ) {
2448b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                    layer->drawForSreenShot();
2449b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                }
2450bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian            }
245174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        }
245274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
245374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // XXX: this is needed on tegra
2454ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian        glEnable(GL_SCISSOR_TEST);
245574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glScissor(0, 0, sw, sh);
245674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
245774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // check for errors and return screen capture
245874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        if (glGetError() != GL_NO_ERROR) {
245974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // error while rendering
246074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            result = INVALID_OPERATION;
246174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        } else {
246274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // allocate shared memory large enough to hold the
246374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // screen capture
246474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            sp<MemoryHeapBase> base(
246574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    new MemoryHeapBase(size, 0, "screen-capture") );
246674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            void* const ptr = base->getBase();
246774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            if (ptr) {
246874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                // capture the screen with glReadPixels()
2469fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian                ScopedTrace _t(ATRACE_TAG, "glReadPixels");
247074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                glReadPixels(0, 0, sw, sh, GL_RGBA, GL_UNSIGNED_BYTE, ptr);
247174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                if (glGetError() == GL_NO_ERROR) {
247274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *heap = base;
247374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *w = sw;
247474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *h = sh;
247574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *f = PIXEL_FORMAT_RGBA_8888;
247674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    result = NO_ERROR;
247774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                }
247874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            } else {
247974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                result = NO_MEMORY;
248074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            }
248174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        }
248274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glEnable(GL_SCISSOR_TEST);
248374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glViewport(0, 0, hw_w, hw_h);
248474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_PROJECTION);
248574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glPopMatrix();
248674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_MODELVIEW);
248774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    } else {
248874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        result = BAD_VALUE;
248974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    }
249074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
249174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // release FBO resources
249274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
249374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glDeleteRenderbuffersOES(1, &tname);
249474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glDeleteFramebuffersOES(1, &name);
2495e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian
2496e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian    hw.compositionComplete();
2497e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian
24989d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block    // ALOGD("screenshot: result = %s", result<0 ? strerror(result) : "OK");
2499c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
250074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    return result;
250174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian}
250274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
250374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
25041b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopianstatus_t SurfaceFlinger::captureScreen(DisplayID dpy,
25051b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        sp<IMemoryHeap>* heap,
250674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t* width, uint32_t* height, PixelFormat* format,
2507bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t sw, uint32_t sh,
2508bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ, uint32_t maxLayerZ)
25091b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian{
25101b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    // only one display supported for now
251199ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten    if (CC_UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
25121b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        return BAD_VALUE;
25131b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
25141b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
25151b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        return INVALID_OPERATION;
25161b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
25171b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    class MessageCaptureScreen : public MessageBase {
25181b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        SurfaceFlinger* flinger;
25191b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        DisplayID dpy;
25201b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        sp<IMemoryHeap>* heap;
25211b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        uint32_t* w;
25221b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        uint32_t* h;
25231b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        PixelFormat* f;
252474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t sw;
252574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t sh;
2526bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ;
2527bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t maxLayerZ;
25281b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        status_t result;
25291b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    public:
25301b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        MessageCaptureScreen(SurfaceFlinger* flinger, DisplayID dpy,
253174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                sp<IMemoryHeap>* heap, uint32_t* w, uint32_t* h, PixelFormat* f,
2532bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                uint32_t sw, uint32_t sh,
2533bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                uint32_t minLayerZ, uint32_t maxLayerZ)
25341b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            : flinger(flinger), dpy(dpy),
2535bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              heap(heap), w(w), h(h), f(f), sw(sw), sh(sh),
2536bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              minLayerZ(minLayerZ), maxLayerZ(maxLayerZ),
2537bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              result(PERMISSION_DENIED)
25381b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
25391b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
25401b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        status_t getResult() const {
25411b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            return result;
25421b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
25431b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        virtual bool handler() {
25441b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
25451b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
25461b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            // if we have secure windows, never allow the screen capture
25471b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            if (flinger->mSecureFrameBuffer)
25481b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                return true;
25491b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
255074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            result = flinger->captureScreenImplLocked(dpy,
2551bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                    heap, w, h, f, sw, sh, minLayerZ, maxLayerZ);
25521b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
25531b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            return true;
25541b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
25551b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    };
25561b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
25571b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    sp<MessageBase> msg = new MessageCaptureScreen(this,
2558bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian            dpy, heap, width, height, format, sw, sh, minLayerZ, maxLayerZ);
25591b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    status_t res = postMessageSync(msg);
25601b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    if (res == NO_ERROR) {
25611b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        res = static_cast<MessageCaptureScreen*>( msg.get() )->getResult();
25621b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    }
25631b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    return res;
25641b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian}
25651b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
25661b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// ---------------------------------------------------------------------------
25671b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
2568b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<Layer> SurfaceFlinger::getLayer(const sp<ISurface>& sur) const
2569edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2570b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<Layer> result;
2571b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    Mutex::Autolock _l(mStateLock);
2572b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    result = mLayerMap.valueFor( sur->asBinder() ).promote();
2573b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return result;
2574b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
25757303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
2576b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// ---------------------------------------------------------------------------
257796f0819f81293076e652792794a961543e6750d7Mathias Agopian
2578b7e930db175c192464cebdeb49eb56cf6dd60114Mathias AgopianClient::Client(const sp<SurfaceFlinger>& flinger)
2579b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    : mFlinger(flinger), mNameGenerator(1)
2580b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{
2581edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2582edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
258396f0819f81293076e652792794a961543e6750d7Mathias AgopianClient::~Client()
258496f0819f81293076e652792794a961543e6750d7Mathias Agopian{
258596f0819f81293076e652792794a961543e6750d7Mathias Agopian    const size_t count = mLayers.size();
258696f0819f81293076e652792794a961543e6750d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
258796f0819f81293076e652792794a961543e6750d7Mathias Agopian        sp<LayerBaseClient> layer(mLayers.valueAt(i).promote());
258896f0819f81293076e652792794a961543e6750d7Mathias Agopian        if (layer != 0) {
258996f0819f81293076e652792794a961543e6750d7Mathias Agopian            mFlinger->removeLayer(layer);
259096f0819f81293076e652792794a961543e6750d7Mathias Agopian        }
2591edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2592edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2593076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
259496f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t Client::initCheck() const {
2595b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return NO_ERROR;
2596edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2597076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
25984f113740180b6512b43723c4728f262882dc9b45Mathias Agopiansize_t Client::attachLayer(const sp<LayerBaseClient>& layer)
2599edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
26004f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    Mutex::Autolock _l(mLock);
26014f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    size_t name = mNameGenerator++;
260296f0819f81293076e652792794a961543e6750d7Mathias Agopian    mLayers.add(name, layer);
260396f0819f81293076e652792794a961543e6750d7Mathias Agopian    return name;
2604edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2605edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2606b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianvoid Client::detachLayer(const LayerBaseClient* layer)
260796f0819f81293076e652792794a961543e6750d7Mathias Agopian{
26084f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    Mutex::Autolock _l(mLock);
260996f0819f81293076e652792794a961543e6750d7Mathias Agopian    // we do a linear search here, because this doesn't happen often
261096f0819f81293076e652792794a961543e6750d7Mathias Agopian    const size_t count = mLayers.size();
261196f0819f81293076e652792794a961543e6750d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
261296f0819f81293076e652792794a961543e6750d7Mathias Agopian        if (mLayers.valueAt(i) == layer) {
261396f0819f81293076e652792794a961543e6750d7Mathias Agopian            mLayers.removeItemsAt(i, 1);
261496f0819f81293076e652792794a961543e6750d7Mathias Agopian            break;
261596f0819f81293076e652792794a961543e6750d7Mathias Agopian        }
261696f0819f81293076e652792794a961543e6750d7Mathias Agopian    }
261796f0819f81293076e652792794a961543e6750d7Mathias Agopian}
26184f113740180b6512b43723c4728f262882dc9b45Mathias Agopiansp<LayerBaseClient> Client::getLayerUser(int32_t i) const
26194f113740180b6512b43723c4728f262882dc9b45Mathias Agopian{
26204f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    Mutex::Autolock _l(mLock);
2621076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBaseClient> lbc;
26224f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    wp<LayerBaseClient> layer(mLayers.valueFor(i));
262396f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (layer != 0) {
262496f0819f81293076e652792794a961543e6750d7Mathias Agopian        lbc = layer.promote();
2625e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE_IF(lbc==0, "getLayerUser(name=%d) is dead", int(i));
2626076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
2627076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return lbc;
2628edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2629edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2630a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
2631a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianstatus_t Client::onTransact(
2632a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
2633a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian{
2634a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // these must be checked
2635a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     IPCThreadState* ipc = IPCThreadState::self();
2636a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     const int pid = ipc->getCallingPid();
2637a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     const int uid = ipc->getCallingUid();
2638a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     const int self_pid = getpid();
263999ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten     if (CC_UNLIKELY(pid != self_pid && uid != AID_GRAPHICS && uid != 0)) {
2640a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian         // we're called from a different process, do the real check
264199b49840d309727678b77403d6cc9f920111623fMathias Agopian         if (!PermissionCache::checkCallingPermission(sAccessSurfaceFlinger))
2642a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian         {
2643e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block             ALOGE("Permission Denial: "
2644a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                     "can't openGlobalTransaction pid=%d, uid=%d", pid, uid);
2645a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian             return PERMISSION_DENIED;
2646a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian         }
2647a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     }
2648a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     return BnSurfaceComposerClient::onTransact(code, data, reply, flags);
2649edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2650a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
2651a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
265296f0819f81293076e652792794a961543e6750d7Mathias Agopiansp<ISurface> Client::createSurface(
26530ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        ISurfaceComposerClient::surface_data_t* params,
2654b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        const String8& name,
2655b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
2656edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t flags)
2657edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2658b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    /*
2659a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     * createSurface must be called from the GL thread so that it can
2660a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     * have access to the GL context.
2661b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     */
2662b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
2663a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    class MessageCreateSurface : public MessageBase {
2664a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        sp<ISurface> result;
2665a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        SurfaceFlinger* flinger;
2666a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        ISurfaceComposerClient::surface_data_t* params;
2667a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        Client* client;
2668a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        const String8& name;
2669a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        DisplayID display;
2670a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        uint32_t w, h;
2671a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        PixelFormat format;
2672a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        uint32_t flags;
2673a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    public:
2674a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        MessageCreateSurface(SurfaceFlinger* flinger,
2675a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                ISurfaceComposerClient::surface_data_t* params,
2676a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                const String8& name, Client* client,
2677a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
2678a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                uint32_t flags)
2679a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            : flinger(flinger), params(params), client(client), name(name),
2680a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian              display(display), w(w), h(h), format(format), flags(flags)
2681a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        {
2682579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        }
2683a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        sp<ISurface> getResult() const { return result; }
2684a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        virtual bool handler() {
2685a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            result = flinger->createSurface(params, name, client,
2686a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                    display, w, h, format, flags);
2687a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            return true;
2688b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        }
2689a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    };
2690b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
2691a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    sp<MessageBase> msg = new MessageCreateSurface(mFlinger.get(),
2692a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            params, name, this, display, w, h, format, flags);
2693a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    mFlinger->postMessageSync(msg);
2694a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    return static_cast<MessageCreateSurface*>( msg.get() )->getResult();
2695b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
2696a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianstatus_t Client::destroySurface(SurfaceID sid) {
2697a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    return mFlinger->removeSurface(this, sid);
2698b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
2699b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
2700b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// ---------------------------------------------------------------------------
2701edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
27029a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::GraphicBufferAlloc() {}
27039a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
27049a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::~GraphicBufferAlloc() {}
27059a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
27069a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h,
2707d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        PixelFormat format, uint32_t usage, status_t* error) {
27089a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(w, h, format, usage));
27099a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    status_t err = graphicBuffer->initCheck();
2710d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian    *error = err;
2711a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (err != 0 || graphicBuffer->handle == 0) {
2712d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        if (err == NO_MEMORY) {
2713d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian            GraphicBuffer::dumpAllocationsToSystemLog();
2714d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        }
2715e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE("GraphicBufferAlloc::createGraphicBuffer(w=%d, h=%d) "
2716a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian             "failed (%s), handle=%p",
2717a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                w, h, strerror(-err), graphicBuffer->handle);
27189a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis        return 0;
27199a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    }
27209a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    return graphicBuffer;
27219a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis}
27229a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
27239a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis// ---------------------------------------------------------------------------
27249a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
2725edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane::GraphicPlane()
2726edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    : mHw(0)
2727edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2728edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2729edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2730edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane::~GraphicPlane() {
2731edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    delete mHw;
2732edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2733edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2734edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool GraphicPlane::initialized() const {
2735edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return mHw ? true : false;
2736edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2737edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
27382b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianint GraphicPlane::getWidth() const {
27392b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    return mWidth;
2740edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2741edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
27422b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianint GraphicPlane::getHeight() const {
27432b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    return mHeight;
27442b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian}
27452b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
27462b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianvoid GraphicPlane::setDisplayHardware(DisplayHardware *hw)
27472b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian{
27482b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mHw = hw;
27492b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
27502b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    // initialize the display orientation transform.
27512b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    // it's a constant that should come from the display driver.
27522b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    int displayOrientation = ISurfaceComposer::eOrientationDefault;
27532b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    char property[PROPERTY_VALUE_MAX];
27542b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    if (property_get("ro.sf.hwrotation", property, NULL) > 0) {
27552b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        //displayOrientation
27562b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        switch (atoi(property)) {
27572b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        case 90:
27582b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            displayOrientation = ISurfaceComposer::eOrientation90;
27592b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            break;
27602b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        case 270:
27612b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            displayOrientation = ISurfaceComposer::eOrientation270;
27622b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            break;
27632b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        }
27642b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    }
27652b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
27662b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float w = hw->getWidth();
27672b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float h = hw->getHeight();
27682b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    GraphicPlane::orientationToTransfrom(displayOrientation, w, h,
27692b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            &mDisplayTransform);
27702b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    if (displayOrientation & ISurfaceComposer::eOrientationSwapMask) {
27712b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayWidth = h;
27722b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayHeight = w;
27732b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    } else {
27742b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayWidth = w;
27752b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayHeight = h;
27762b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    }
27772b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
27782b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    setOrientation(ISurfaceComposer::eOrientationDefault);
2779edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2780edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2781edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t GraphicPlane::orientationToTransfrom(
2782edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int orientation, int w, int h, Transform* tr)
2783eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian{
2784eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    uint32_t flags = 0;
2785edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (orientation) {
2786edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientationDefault:
2787eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_0;
2788eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        break;
2789edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientation90:
2790eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_90;
2791edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
2792edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientation180:
2793eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_180;
2794edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
2795edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientation270:
2796eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_270;
2797edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
2798edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    default:
2799edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return BAD_VALUE;
2800edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2801eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    tr->set(flags, w, h);
2802edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
2803edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2804edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2805edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t GraphicPlane::setOrientation(int orientation)
2806edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2807edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // If the rotation can be handled in hardware, this is where
2808edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // the magic should happen.
28092b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
28102b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const DisplayHardware& hw(displayHardware());
28112b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float w = mDisplayWidth;
28122b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float h = mDisplayHeight;
28132b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mWidth = int(w);
28142b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mHeight = int(h);
28152b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
28162b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    Transform orientationTransform;
2817eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    GraphicPlane::orientationToTransfrom(orientation, w, h,
2818eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian            &orientationTransform);
2819eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    if (orientation & ISurfaceComposer::eOrientationSwapMask) {
2820eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        mWidth = int(h);
2821eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        mHeight = int(w);
2822edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2823eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian
28240d1318b974feba2e6ff13e36a1781343c2fce045Mathias Agopian    mOrientation = orientation;
28252b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mGlobalTransform = mDisplayTransform * orientationTransform;
2826edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
2827edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2828edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2829edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst DisplayHardware& GraphicPlane::displayHardware() const {
2830edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return *mHw;
2831edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2832edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
283359119e658a12279e8fff508f8773843de2d90917Mathias AgopianDisplayHardware& GraphicPlane::editDisplayHardware() {
283459119e658a12279e8fff508f8773843de2d90917Mathias Agopian    return *mHw;
283559119e658a12279e8fff508f8773843de2d90917Mathias Agopian}
283659119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2837edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst Transform& GraphicPlane::transform() const {
2838edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return mGlobalTransform;
2839edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2840edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2841076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias AgopianEGLDisplay GraphicPlane::getEGLDisplay() const {
2842076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return mHw->getEGLDisplay();
2843076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
2844076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
2845edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
2846edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2847edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
2848