SurfaceFlinger.cpp revision 62f7114719d2009dca7dd120f0fe29a24bd77a40
1edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/*
2edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
3edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
4edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * you may not use this file except in compliance with the License.
6edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * You may obtain a copy of the License at
7edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
8edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
10edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * See the License for the specific language governing permissions and
14edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * limitations under the License.
15edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */
16edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
17edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdlib.h>
18edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdio.h>
19edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdint.h>
20edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <unistd.h>
21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <fcntl.h>
22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <errno.h>
23edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <math.h>
24a837ba778f2d7a5170b37aa33624d9b9711c354dJean-Baptiste Queru#include <limits.h>
25edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/types.h>
26edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/stat.h>
27edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/ioctl.h>
28edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/log.h>
30edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/properties.h>
31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
32c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IPCThreadState.h>
33c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IServiceManager.h>
347303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian#include <binder/MemoryHeapBase.h>
3599b49840d309727678b77403d6cc9f920111623fMathias Agopian#include <binder/PermissionCache.h>
367303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
37edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String8.h>
38edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String16.h>
39edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/StopWatch.h>
40edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
413330b203039dea366d4981db1408a460134b2d2cMathias Agopian#include <ui/GraphicBufferAllocator.h>
4235b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian#include <ui/GraphicLog.h>
43edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/PixelFormat.h>
44edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <pixelflinger/pixelflinger.h>
46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <GLES/gl.h>
47edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
48edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h"
491f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian#include "GLExtensions.h"
508afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian#include "DdmConnection.h"
51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h"
52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerDim.h"
53118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian#include "LayerScreenshot.h"
54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h"
55edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "DisplayHardware/DisplayHardware.h"
57a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian#include "DisplayHardware/HWComposer.h"
58edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
59a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian#include <private/surfaceflinger/SharedBufferStack.h>
60a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
61a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian/* ideally AID_GRAPHICS would be in a semi-public header
62a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian * or there would be a way to map a user/group name to its id
63a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian */
64a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian#ifndef AID_GRAPHICS
65a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian#define AID_GRAPHICS 1003
66a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian#endif
67a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias 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        mConsoleSignals(0),
100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mSecureFrameBuffer(0)
101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    init();
103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::init()
106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    LOGI("SurfaceFlinger is starting");
108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // debugging stuff...
110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char value[PROPERTY_VALUE_MAX];
1118afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    property_get("debug.sf.showupdates", value, "0");
113edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDebugRegion = atoi(value);
1148afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    property_get("debug.sf.showbackground", value, "0");
116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDebugBackground = atoi(value);
117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
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    }
1238afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
12478fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian    LOGI_IF(mDebugRegion,       "showupdates enabled");
12578fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian    LOGI_IF(mDebugBackground,   "showbackground enabled");
1268afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    LOGI_IF(mDebugDDMS,         "DDMS debugging enabled");
127edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::~SurfaceFlinger()
130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDeleteTextures(1, &mWormholeTexName);
132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1347303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopiansp<IMemoryHeap> SurfaceFlinger::getCblk() const
135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1367303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    return mServerHeap;
137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1397e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopiansp<ISurfaceComposerClient> SurfaceFlinger::createConnection()
140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
14196f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<ISurfaceComposerClient> bclient;
14296f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<Client> client(new Client(this));
14396f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = client->initCheck();
14496f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR) {
14596f0819f81293076e652792794a961543e6750d7Mathias Agopian        bclient = client;
146edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
147edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return bclient;
148edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
149edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1509a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc()
1519a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis{
1529a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc());
1539a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    return gba;
1549a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis}
155b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst GraphicPlane& SurfaceFlinger::graphicPlane(int dpy) const
157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    LOGE_IF(uint32_t(dpy) >= DISPLAY_COUNT, "Invalid DisplayID %d", dpy);
159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(mGraphicPlanes[dpy]);
160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return plane;
161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane& SurfaceFlinger::graphicPlane(int dpy)
164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return const_cast<GraphicPlane&>(
166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const_cast<SurfaceFlinger const *>(this)->graphicPlane(dpy));
167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::bootFinished()
170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t now = systemTime();
172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t duration = now - mBootTime;
1738b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber    LOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
1743330b203039dea366d4981db1408a460134b2d2cMathias Agopian    mBootFinished = true;
1751f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
1761f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // wait patiently for the window manager death
1771f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    const String16 name("window");
1781f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    sp<IBinder> window(defaultServiceManager()->getService(name));
1791f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    if (window != 0) {
1801f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian        window->linkToDeath(this);
1811f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    }
1821f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
1831f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // stop boot animation
184a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    property_set("ctl.stop", "bootanim");
185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1871f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopianvoid SurfaceFlinger::binderDied(const wp<IBinder>& who)
1881f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian{
1891f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // the window manager died on us. prepare its eulogy.
1901f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
1911f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // reset screen orientation
1921f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    setOrientation(0, eOrientationDefault, 0);
1931f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
1941f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // restart the boot-animation
1951f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    property_set("ctl.start", "bootanim");
1961f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian}
1971f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::onFirstRef()
199edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
200edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY);
201edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
202edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // Wait for the main thread to be done with its initialization
203edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mReadyToRunBarrier.wait();
204edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
205edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
206edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic inline uint16_t pack565(int r, int g, int b) {
207edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return (r<<11)|(g<<5)|b;
208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
209edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
210edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::readyToRun()
211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    LOGI(   "SurfaceFlinger's main thread ready to run. "
213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            "Initializing graphics H/W...");
214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // we only support one display currently
216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int dpy = 0;
217edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    {
219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // initialize the main display
220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GraphicPlane& plane(graphicPlane(dpy));
221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        DisplayHardware* const hw = new DisplayHardware(this, dpy);
222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        plane.setDisplayHardware(hw);
223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2257303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    // create the shared control-block
2267303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    mServerHeap = new MemoryHeapBase(4096,
2277303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian            MemoryHeapBase::READ_ONLY, "SurfaceFlinger read-only heap");
2287303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    LOGE_IF(mServerHeap==0, "can't create shared memory dealer");
2298b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
2307303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    mServerCblk = static_cast<surface_flinger_cblk_t*>(mServerHeap->getBase());
2317303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    LOGE_IF(mServerCblk==0, "can't get to shared control block's address");
2328b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
2337303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    new(mServerCblk) surface_flinger_cblk_t;
2347303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize primary screen
236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // (other display should be initialized in the same manner, but
237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // asynchronously, as they could come and go. None of this is supported
238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // yet).
239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(graphicPlane(dpy));
240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw = plane.displayHardware();
241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint32_t w = hw.getWidth();
242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint32_t h = hw.getHeight();
243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint32_t f = hw.getFormat();
244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    hw.makeCurrent();
245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize the shared control block
247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mServerCblk->connected |= 1<<dpy;
248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    display_cblk_t* dcblk = mServerCblk->displays + dpy;
249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    memset(dcblk, 0, sizeof(display_cblk_t));
2502b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    dcblk->w            = plane.getWidth();
2512b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    dcblk->h            = plane.getHeight();
252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->format       = f;
253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->orientation  = ISurfaceComposer::eOrientationDefault;
254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->xdpi         = hw.getDpiX();
255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->ydpi         = hw.getDpiY();
256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->fps          = hw.getRefreshRate();
257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->density      = hw.getDensity();
258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
259edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // Initialize OpenGL|ES
260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
2618b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber    glPixelStorei(GL_PACK_ALIGNMENT, 4);
262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glEnableClientState(GL_VERTEX_ARRAY);
263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glEnable(GL_SCISSOR_TEST);
264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glShadeModel(GL_FLAT);
265edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_DITHER);
266edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_CULL_FACE);
267edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint16_t g0 = pack565(0x0F,0x1F,0x0F);
269edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint16_t g1 = pack565(0x17,0x2f,0x17);
2709575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    const uint16_t wormholeTexData[4] = { g0, g1, g1, g0 };
271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glGenTextures(1, &mWormholeTexName);
272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glBindTexture(GL_TEXTURE_2D, mWormholeTexName);
273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0,
2789575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis            GL_RGB, GL_UNSIGNED_SHORT_5_6_5, wormholeTexData);
2799575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis
2809575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    const uint16_t protTexData[] = { pack565(0x03, 0x03, 0x03) };
2819575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glGenTextures(1, &mProtectedTexName);
2829575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glBindTexture(GL_TEXTURE_2D, mProtectedTexName);
2839575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2849575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2859575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
2869575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
2879575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0,
2889575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis            GL_RGB, GL_UNSIGNED_SHORT_5_6_5, protTexData);
289edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
290edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glViewport(0, 0, w, h);
291edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glMatrixMode(GL_PROJECTION);
292edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glLoadIdentity();
293ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    // put the origin in the left-bottom corner
294ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    glOrthof(0, w, 0, h, 0, 1); // l=0, r=w ; b=0, t=h
295edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mReadyToRunBarrier.open();
297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     *  We're now ready to accept clients...
300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
301edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
302a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    // start boot animation
303a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    property_set("ctl.start", "bootanim");
3048b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if 0
310edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark -
311edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark Events Handler
312edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif
313edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
314edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::waitForEvent()
315edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
316f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    while (true) {
317f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        nsecs_t timeout = -1;
318bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        sp<MessageBase> msg = mEventQueue.waitMessage(timeout);
3190408772e34931351d062f2088b611325ddaa6cdbMathias Agopian        if (msg != 0) {
3200408772e34931351d062f2088b611325ddaa6cdbMathias Agopian            switch (msg->what) {
3210408772e34931351d062f2088b611325ddaa6cdbMathias Agopian                case MessageQueue::INVALIDATE:
3220408772e34931351d062f2088b611325ddaa6cdbMathias Agopian                    // invalidate message, just return to the main loop
3230408772e34931351d062f2088b611325ddaa6cdbMathias Agopian                    return;
324edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
325edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
326edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
327edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
328edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
329edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::signalEvent() {
330f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    mEventQueue.invalidate();
331edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
332edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
333582270d69db94286a248bd829f1ae6f910d45124Jamie Gennisbool SurfaceFlinger::authenticateSurfaceTexture(
334582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis        const sp<ISurfaceTexture>& surfaceTexture) const {
335134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    Mutex::Autolock _l(mStateLock);
336582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis    sp<IBinder> surfaceTextureBinder(surfaceTexture->asBinder());
337134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
338134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // Check the visible layer list for the ISurface
339134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
340134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    size_t count = currentLayers.size();
341134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    for (size_t i=0 ; i<count ; i++) {
342134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        const sp<LayerBase>& layer(currentLayers[i]);
343134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        sp<LayerBaseClient> lbc(layer->getLayerBaseClient());
344582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis        if (lbc != NULL) {
345582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder();
346582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            if (lbcBinder == surfaceTextureBinder) {
347582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis                return true;
348582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            }
349134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        }
350134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    }
351134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
352134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // Check the layers in the purgatory.  This check is here so that if a
353582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis    // SurfaceTexture gets destroyed before all the clients are done using it,
354582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis    // the error will not be reported as "surface XYZ is not authenticated", but
355134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // will instead fail later on when the client tries to use the surface,
356134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // which should be reported as "surface XYZ returned an -ENODEV".  The
357134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // purgatorized layers are no less authentic than the visible ones, so this
358134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // should not cause any harm.
359134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    size_t purgatorySize =  mLayerPurgatory.size();
360134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    for (size_t i=0 ; i<purgatorySize ; i++) {
361134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
362134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        sp<LayerBaseClient> lbc(layer->getLayerBaseClient());
363582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis        if (lbc != NULL) {
364582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder();
365582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            if (lbcBinder == surfaceTextureBinder) {
366582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis                return true;
367582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            }
368134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        }
369134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    }
370134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
371134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    return false;
372134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis}
373134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
374bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg,
375bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        nsecs_t reltime, uint32_t flags)
376edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
377bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    return mEventQueue.postMessage(msg, reltime, flags);
378bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian}
379bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
380bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,
381bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        nsecs_t reltime, uint32_t flags)
382bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian{
383bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    status_t res = mEventQueue.postMessage(msg, reltime, flags);
384bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    if (res == NO_ERROR) {
385bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        msg->wait();
386bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    }
387bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    return res;
388edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
389edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
390edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
391edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if 0
392edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark -
393edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark Main loop
394edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif
395edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
396edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool SurfaceFlinger::threadLoop()
397edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
398edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    waitForEvent();
399edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
400edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // check for transactions
401edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(mConsoleSignals)) {
402edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        handleConsoleEvents();
403edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
404edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
405698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    // if we're in a global transaction, don't do anything.
406698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
407698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    uint32_t transactionFlags = peekTransactionFlags(mask);
408698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    if (UNLIKELY(transactionFlags)) {
409698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        handleTransaction(transactionFlags);
410edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
411edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
412edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // post surfaces (if needed)
413edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    handlePageFlip();
414edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
4153a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian    if (mDirtyRegion.isEmpty()) {
4163a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian        // nothing new to do.
4173a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian        return true;
4183a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian    }
4193a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian
420a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    if (UNLIKELY(mHwWorkListDirty)) {
421a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        // build the h/w work list
422a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        handleWorkList();
423a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
424a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
425edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw(graphicPlane(0).displayHardware());
426a402c4c9913cfbc6c3da21719c57a93a11f091f0Jamie Gennis    if (LIKELY(hw.canDraw())) {
427edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // repaint the framebuffer (if needed)
42835b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian
42935b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        const int index = hw.getCurrentBufferIndex();
43035b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        GraphicLog& logger(GraphicLog::getInstance());
43135b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian
43235b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        logger.log(GraphicLog::SF_REPAINT, index);
433edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        handleRepaint();
434edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
43574faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian        // inform the h/w that we're done compositing
43635b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        logger.log(GraphicLog::SF_COMPOSITION_COMPLETE, index);
43774faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian        hw.compositionComplete();
43874faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian
43935b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        logger.log(GraphicLog::SF_SWAP_BUFFERS, index);
4408392b504bdf63ac7820c79c7217a89f2b2411bd0Antti Hatala        postFramebuffer();
4418392b504bdf63ac7820c79c7217a89f2b2411bd0Antti Hatala
44235b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        logger.log(GraphicLog::SF_REPAINT_DONE, index);
443edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
444edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // pretend we did the post
445e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian        hw.compositionComplete();
446edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        usleep(16667); // 60 fps period
447edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
448edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return true;
449edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
450edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
451edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer()
452edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
4533a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian    // this should never happen. we do the flip anyways so we don't
4543a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian    // risk to cause a deadlock with hwc
4553a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian    LOGW_IF(mSwapRegion.isEmpty(), "mSwapRegion is empty");
456a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
457a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    const nsecs_t now = systemTime();
458a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = now;
459a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    hw.flip(mSwapRegion);
460a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mLastSwapBufferTime = systemTime() - now;
461a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = 0;
462a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mSwapRegion.clear();
463edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
464edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
465edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleConsoleEvents()
466edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
467edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // something to do with the console
468edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw = graphicPlane(0).displayHardware();
469edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
470edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int what = android_atomic_and(0, &mConsoleSignals);
471edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (what & eConsoleAcquired) {
472edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        hw.acquireScreen();
4739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // this is a temporary work-around, eventually this should be called
4749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // by the power-manager
475abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        SurfaceFlinger::turnElectronBeamOn(mElectronBeamAnimationMode);
476edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
477edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
478edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (what & eConsoleReleased) {
47959119e658a12279e8fff508f8773843de2d90917Mathias Agopian        if (hw.isScreenAcquired()) {
480edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            hw.releaseScreen();
481edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
482edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
483edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
484edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDirtyRegion.set(hw.bounds());
485edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
486edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
487edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
488edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
489ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    Mutex::Autolock _l(mStateLock);
490ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    const nsecs_t now = systemTime();
491ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = now;
492ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
493ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // Here we're guaranteed that some transaction flags are set
494ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // so we can call handleTransactionLocked() unconditionally.
495ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // We call getTransactionFlags(), which will also clear the flags,
496ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // with mStateLock held to guarantee that mCurrentState won't change
497ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // until the transaction is committed.
498ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
499ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
500ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    transactionFlags = getTransactionFlags(mask);
501ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    handleTransactionLocked(transactionFlags);
502ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
503ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mLastTransactionTime = systemTime() - now;
504ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = 0;
505ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    invalidateHwcGeometry();
506ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // here the transaction has been committed
5073d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian}
508edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
509ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopianvoid SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
5103d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{
5113d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    const LayerVector& currentLayers(mCurrentState.layersSortedByZ);
512edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t count = currentLayers.size();
513edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
514edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
515edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Traversal of the children
516edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * (perform the transaction for each of them if needed)
517edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
518edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
519edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const bool layersNeedTransaction = transactionFlags & eTraversalNeeded;
520edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (layersNeedTransaction) {
521edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (size_t i=0 ; i<count ; i++) {
522076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            const sp<LayerBase>& layer = currentLayers[i];
523edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
524edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (!trFlags) continue;
525edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
526edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const uint32_t flags = layer->doTransaction(0);
527edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (flags & Layer::eVisibleRegion)
528edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mVisibleRegionsDirty = true;
529edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
530edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
531edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
532edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
533edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Perform our own transaction if needed
534edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
535edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
536edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (transactionFlags & eTransactionNeeded) {
537edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (mCurrentState.orientation != mDrawingState.orientation) {
538edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // the orientation has changed, recompute all visible regions
539edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // and invalidate everything.
540edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
541edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int dpy = 0;
542edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int orientation = mCurrentState.orientation;
54321230c6410bdab13cd2bd274da54b1e4061b6035Jeff Brown            // Currently unused: const uint32_t flags = mCurrentState.orientationFlags;
544edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            GraphicPlane& plane(graphicPlane(dpy));
545edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            plane.setOrientation(orientation);
546edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
547edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // update the shared control block
548edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const DisplayHardware& hw(plane.displayHardware());
549edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            volatile display_cblk_t* dcblk = mServerCblk->displays + dpy;
550edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dcblk->orientation = orientation;
5512b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            dcblk->w = plane.getWidth();
5522b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            dcblk->h = plane.getHeight();
553edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
554edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
555edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mDirtyRegion.set(hw.bounds());
556edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
557edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5580aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        if (currentLayers.size() > mDrawingState.layersSortedByZ.size()) {
5590aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            // layers have been added
560edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
561edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5630aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        // some layers might have been removed, so
5640aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        // we need to update the regions they're exposing.
5650aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        if (mLayersRemoved) {
56648d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian            mLayersRemoved = false;
567edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
5680aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            const LayerVector& previousLayers(mDrawingState.layersSortedByZ);
5693d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian            const size_t count = previousLayers.size();
5703d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian            for (size_t i=0 ; i<count ; i++) {
5710aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                const sp<LayerBase>& layer(previousLayers[i]);
5720aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                if (currentLayers.indexOf( layer ) < 0) {
5730aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                    // this layer is not visible anymore
5745d7126b625c8c4a7b945e8c247b63abff7bc13b6Mathias Agopian                    mDirtyRegionRemovedLayer.orSelf(layer->visibleRegionScreen);
5750aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                }
5760aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            }
577edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
578edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
579edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
580edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    commitTransaction();
581edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
582edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
583edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::computeVisibleRegions(
5841bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian    const LayerVector& currentLayers, Region& dirtyRegion, Region& opaqueRegion)
585edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
586edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(graphicPlane(0));
587edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Transform& planeTransform(plane.transform());
588ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian    const DisplayHardware& hw(plane.displayHardware());
589ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian    const Region screenRegion(hw.bounds());
590edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
591edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveOpaqueLayers;
592edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveCoveredLayers;
593edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region dirty;
594edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
595edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    bool secureFrameBuffer = false;
596edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
597edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t i = currentLayers.size();
598edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    while (i--) {
599076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        const sp<LayerBase>& layer = currentLayers[i];
600edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->validateVisibility(planeTransform);
601edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
602edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // start with the whole surface at its current location
603970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian        const Layer::State& s(layer->drawingState());
604edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
605ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
606ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * opaqueRegion: area of a surface that is fully opaque.
607ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
608edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region opaqueRegion;
609ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
610ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
611ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visibleRegion: area of a surface that is visible on screen
612ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * and not fully transparent. This is essentially the layer's
613ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * footprint minus the opaque regions above it.
614ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * Areas covered by a translucent surface are considered visible.
615ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
616edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region visibleRegion;
617ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
618ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
619ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * coveredRegion: area of a surface that is covered by all
620ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visible regions above it (which includes the translucent areas).
621ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
622edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region coveredRegion;
623ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
624ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
625ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // handle hidden surfaces by setting the visible region to empty
626970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian        if (LIKELY(!(s.flags & ISurfaceComposer::eLayerHidden) && s.alpha)) {
627a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            const bool translucent = !layer->isOpaque();
628970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian            const Rect bounds(layer->visibleBounds());
629edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            visibleRegion.set(bounds);
630ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            visibleRegion.andSelf(screenRegion);
631ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            if (!visibleRegion.isEmpty()) {
632ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // Remove the transparent area from the visible region
633ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (translucent) {
634ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    visibleRegion.subtractSelf(layer->transparentRegionScreen);
635ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
636edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
637ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // compute the opaque region
638ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                const int32_t layerOrientation = layer->getOrientation();
639ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (s.alpha==255 && !translucent &&
640ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                        ((layerOrientation & Transform::ROT_INVALID) == false)) {
641ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    // the opaque region is the layer's footprint
642ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    opaqueRegion = visibleRegion;
643ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
644edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
645edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
646edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
647ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Clip the covered region to the visible region
648ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        coveredRegion = aboveCoveredLayers.intersect(visibleRegion);
649ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
650ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveCoveredLayers for next (lower) layer
651ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        aboveCoveredLayers.orSelf(visibleRegion);
652ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
653edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // subtract the opaque region covered by the layers above us
654edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        visibleRegion.subtractSelf(aboveOpaqueLayers);
655edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
656edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // compute this layer's dirty region
657edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (layer->contentDirty) {
658edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // we need to invalidate the whole region
659edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dirty = visibleRegion;
660edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // as well, as the old visible region
661edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dirty.orSelf(layer->visibleRegionScreen);
662edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->contentDirty = false;
663edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
664a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian            /* compute the exposed region:
665ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   the exposed region consists of two components:
666ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   1) what's VISIBLE now and was COVERED before
667ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   2) what's EXPOSED now less what was EXPOSED before
668ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
669ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * note that (1) is conservative, we start with the whole
670ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * visible region but only keep what used to be covered by
671ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * something -- which mean it may have been exposed.
672ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
673ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * (2) handles areas that were not covered by anything but got
674ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * exposed because of a resize.
675a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian             */
676ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region newExposed = visibleRegion - coveredRegion;
677ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldVisibleRegion = layer->visibleRegionScreen;
678ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldCoveredRegion = layer->coveredRegionScreen;
679ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldExposed = oldVisibleRegion - oldCoveredRegion;
680ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed);
681edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
682edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirty.subtractSelf(aboveOpaqueLayers);
683edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
684edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // accumulate to the screen dirty region
685edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirtyRegion.orSelf(dirty);
686edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
687ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveOpaqueLayers for next (lower) layer
688edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        aboveOpaqueLayers.orSelf(opaqueRegion);
6898b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
690edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // Store the visible region is screen space
691edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setVisibleRegion(visibleRegion);
692edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setCoveredRegion(coveredRegion);
693edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
694970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian        // If a secure layer is partially visible, lock-down the screen!
695edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (layer->isSecure() && !visibleRegion.isEmpty()) {
696edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            secureFrameBuffer = true;
697edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
698edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
699edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
700970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian    // invalidate the areas where a layer was removed
701970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian    dirtyRegion.orSelf(mDirtyRegionRemovedLayer);
702970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian    mDirtyRegionRemovedLayer.clear();
703970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian
704edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mSecureFrameBuffer = secureFrameBuffer;
705edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    opaqueRegion = aboveOpaqueLayers;
706edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
707edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
708edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
709edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::commitTransaction()
710edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
711edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDrawingState = mCurrentState;
71228378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    mTransationPending = false;
713cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mTransactionCV.broadcast();
714edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
715edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
716edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handlePageFlip()
717edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
718edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    bool visibleRegions = mVisibleRegionsDirty;
7191bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian    const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
720edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    visibleRegions |= lockPageFlip(currentLayers);
721edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
722edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const DisplayHardware& hw = graphicPlane(0).displayHardware();
723edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const Region screenRegion(hw.bounds());
724edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (visibleRegions) {
725edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            Region opaqueRegion;
726edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            computeVisibleRegions(currentLayers, mDirtyRegion, opaqueRegion);
7274da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
7284da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            /*
7294da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian             *  rebuild the visible layer list
7304da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian             */
7311bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian            const size_t count = currentLayers.size();
7324da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            mVisibleLayersSortedByZ.clear();
7334da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            mVisibleLayersSortedByZ.setCapacity(count);
7344da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            for (size_t i=0 ; i<count ; i++) {
7354da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian                if (!currentLayers[i]->visibleRegionScreen.isEmpty())
7364da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian                    mVisibleLayersSortedByZ.add(currentLayers[i]);
7374da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            }
7384da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
739edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mWormholeRegion = screenRegion.subtract(opaqueRegion);
740edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = false;
741ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian            invalidateHwcGeometry();
742edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
743edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
744edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    unlockPageFlip(currentLayers);
7450dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian
7460dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    mDirtyRegion.orSelf(getAndClearInvalidateRegion());
747edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDirtyRegion.andSelf(screenRegion);
748edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
749edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
750ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopianvoid SurfaceFlinger::invalidateHwcGeometry()
751ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian{
752ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian    mHwWorkListDirty = true;
753ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian}
754ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian
755edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool SurfaceFlinger::lockPageFlip(const LayerVector& currentLayers)
756edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
757edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    bool recomputeVisibleRegions = false;
758edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t count = currentLayers.size();
759076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBase> const* layers = currentLayers.array();
760edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (size_t i=0 ; i<count ; i++) {
761b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
762edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->lockPageFlip(recomputeVisibleRegions);
763edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
764edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return recomputeVisibleRegions;
765edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
766edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
767edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::unlockPageFlip(const LayerVector& currentLayers)
768edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
769edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(graphicPlane(0));
770edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Transform& planeTransform(plane.transform());
771edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t count = currentLayers.size();
772076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBase> const* layers = currentLayers.array();
773edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (size_t i=0 ; i<count ; i++) {
774b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
775edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->unlockPageFlip(planeTransform, mDirtyRegion);
776edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
777edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
778edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
779a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopianvoid SurfaceFlinger::handleWorkList()
780a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian{
781a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    mHwWorkListDirty = false;
782a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    HWComposer& hwc(graphicPlane(0).displayHardware().getHwComposer());
783a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    if (hwc.initCheck() == NO_ERROR) {
784a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        const Vector< sp<LayerBase> >& currentLayers(mVisibleLayersSortedByZ);
785a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        const size_t count = currentLayers.size();
786a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        hwc.createWorkList(count);
78745721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        hwc_layer_t* const cur(hwc.getLayers());
78845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        for (size_t i=0 ; cur && i<count ; i++) {
78945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            currentLayers[i]->setGeometry(&cur[i]);
79053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian            if (mDebugDisableHWC || mDebugRegion) {
79173d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian                cur[i].compositionType = HWC_FRAMEBUFFER;
79273d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian                cur[i].flags |= HWC_SKIP_LAYER;
79373d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian            }
794a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        }
795a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
796a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian}
797b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian
798edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleRepaint()
799edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
800b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // compute the invalid region
8010656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian    mSwapRegion.orSelf(mDirtyRegion);
802edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
803edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(mDebugRegion)) {
804edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        debugFlashRegions();
805edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
806edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
807b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // set the frame buffer
808b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
809b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    glMatrixMode(GL_MODELVIEW);
810b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    glLoadIdentity();
811edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
812edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t flags = hw.getFlags();
8138b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber    if ((flags & DisplayHardware::SWAP_RECTANGLE) ||
8148b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber        (flags & DisplayHardware::BUFFER_PRESERVED))
815df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian    {
81629d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // we can redraw only what's dirty, but since SWAP_RECTANGLE only
81729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // takes a rectangle, we must make sure to update that whole
81829d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // rectangle in that case
81929d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        if (flags & DisplayHardware::SWAP_RECTANGLE) {
820b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            // TODO: we really should be able to pass a region to
82129d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // SWAP_RECTANGLE so that we don't have to redraw all this.
8220656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian            mDirtyRegion.set(mSwapRegion.bounds());
82329d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        } else {
82429d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // in the BUFFER_PRESERVED case, obviously, we can update only
82529d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // what's needed and nothing more.
82629d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // NOTE: this is NOT a common case, as preserving the backbuffer
82729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // is costly and usually involves copying the whole update back.
82829d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        }
829edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
83095a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian        if (flags & DisplayHardware::PARTIAL_UPDATES) {
83129d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // We need to redraw the rectangle that will be updated
832df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian            // (pushed to the framebuffer).
83395a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian            // This is needed because PARTIAL_UPDATES only takes one
83429d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // rectangle instead of a region (see DisplayHardware::flip())
8350656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian            mDirtyRegion.set(mSwapRegion.bounds());
836edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
83729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // we need to redraw everything (the whole screen)
838edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mDirtyRegion.set(hw.bounds());
8390656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian            mSwapRegion = mDirtyRegion;
840edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
841edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
842edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
8439c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    setupHardwareComposer(mDirtyRegion);
844edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    composeSurfaces(mDirtyRegion);
845edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
8469c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    // update the swap region and clear the dirty region
8479c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    mSwapRegion.orSelf(mDirtyRegion);
848edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDirtyRegion.clear();
849edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
850edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
8519c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopianvoid SurfaceFlinger::setupHardwareComposer(Region& dirtyInOut)
852edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
853f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
854f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    HWComposer& hwc(hw.getHwComposer());
855f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    hwc_layer_t* const cur(hwc.getLayers());
856f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    if (!cur) {
8579c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        return;
858edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
859a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
8604da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian    const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
86145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    size_t count = layers.size();
862a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
863f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    LOGE_IF(hwc.getNumLayers() != count,
86445721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            "HAL number of layers (%d) doesn't match surfaceflinger (%d)",
86545721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            hwc.getNumLayers(), count);
866a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
86745721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    // just to be extra-safe, use the smallest count
86824925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling    if (hwc.initCheck() == NO_ERROR) {
86924925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling        count = count < hwc.getNumLayers() ? count : hwc.getNumLayers();
87024925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling    }
871a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
87245721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    /*
87345721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     *  update the per-frame h/w composer data for each layer
87445721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     *  and build the transparent region of the FB
87545721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     */
876f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
877f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
878f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        layer->setPerFrameData(&cur[i]);
879f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    }
8809c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    const size_t fbLayerCount = hwc.getLayerCount(HWC_FRAMEBUFFER);
881f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    status_t err = hwc.prepare();
882f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    LOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
883f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian
884f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    if (err == NO_ERROR) {
8859c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // what's happening here is tricky.
8869c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // we want to clear all the layers with the CLEAR_FB flags
8879c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // that are opaque.
8889c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // however, since some GPU are efficient at preserving
8899c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // the backbuffer, we want to take advantage of that so we do the
8909c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // clear only in the dirty region (other areas will be preserved
8919c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // on those GPUs).
8929c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        //   NOTE: on non backbuffer preserving GPU, the dirty region
8939c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        //   has already been expanded as needed, so the code is correct
8949c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        //   there too.
8959c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        //
8969c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // However, the content of the framebuffer cannot be trusted when
8979c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // we switch to/from FB/OVERLAY, in which case we need to
8989c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // expand the dirty region to those areas too.
8999c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        //
9009c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // Note also that there is a special case when switching from
9019c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // "no layers in FB" to "some layers in FB", where we need to redraw
9029c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // the entire FB, since some areas might contain uninitialized
9039c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // data.
9049c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        //
9059c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // Also we want to make sure to not clear areas that belong to
9063a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian        // layers above that won't redraw (we would just be erasing them),
9079c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // that is, we can't erase anything outside the dirty region.
908a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
9099c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        Region transparent;
910f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian
9119c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        if (!fbLayerCount && hwc.getLayerCount(HWC_FRAMEBUFFER)) {
9129c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian            transparent.set(hw.getBounds());
9139c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian            dirtyInOut = transparent;
9149c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        } else {
9159c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian            for (size_t i=0 ; i<count ; i++) {
9169c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                const sp<LayerBase>& layer(layers[i]);
9179c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                if ((cur[i].hints & HWC_HINT_CLEAR_FB) && layer->isOpaque()) {
9189c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                    transparent.orSelf(layer->visibleRegionScreen);
9199c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                }
9209c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                bool isOverlay = (cur[i].compositionType != HWC_FRAMEBUFFER);
9219c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                if (isOverlay != layer->isOverlay()) {
9229c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                    // we transitioned to/from overlay, so add this layer
9239c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                    // to the dirty region so the framebuffer can be either
9249c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                    // cleared or redrawn.
9259c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                    dirtyInOut.orSelf(layer->visibleRegionScreen);
9269c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                }
9279c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                layer->setOverlay(isOverlay);
928f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian            }
9299c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian            // don't erase stuff outside the dirty region
9309c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian            transparent.andSelf(dirtyInOut);
931f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        }
932f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian
933f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        /*
934f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian         *  clear the area of the FB that need to be transparent
935f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian         */
936f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        if (!transparent.isEmpty()) {
937f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian            glClearColor(0,0,0,0);
938f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian            Region::const_iterator it = transparent.begin();
939f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian            Region::const_iterator const end = transparent.end();
940f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian            const int32_t height = hw.getHeight();
941f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian            while (it != end) {
942f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian                const Rect& r(*it++);
943f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian                const GLint sy = height - (r.top + r.height());
944f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian                glScissor(r.left, sy, r.width(), r.height());
945f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian                glClear(GL_COLOR_BUFFER_BIT);
946f20a32415d055336bc6016fa2de36d126db32746Mathias Agopian            }
947a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        }
948a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
949f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian}
950f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian
951f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopianvoid SurfaceFlinger::composeSurfaces(const Region& dirty)
952f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian{
953cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
954cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian    HWComposer& hwc(hw.getHwComposer());
955cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian
956cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian    const size_t fbLayerCount = hwc.getLayerCount(HWC_FRAMEBUFFER);
957cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian    if (UNLIKELY(fbLayerCount && !mWormholeRegion.isEmpty())) {
958f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        // should never happen unless the window manager has a bug
959f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        // draw something...
960f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        drawWormhole();
961f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    }
96245721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian
96345721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    /*
96445721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     * and then, render the layers targeted at the framebuffer
96545721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     */
966cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian    hwc_layer_t* const cur(hwc.getLayers());
967f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
968f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    size_t count = layers.size();
96945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
9709c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        if (cur && (cur[i].compositionType != HWC_FRAMEBUFFER)) {
971f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian            continue;
97245721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        }
97345721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
97445721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        const Region clip(dirty.intersect(layer->visibleRegionScreen));
97545721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        if (!clip.isEmpty()) {
97645721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            layer->draw(clip);
97745721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        }
97845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    }
979edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
980edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
981edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::debugFlashRegions()
982edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
9830a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
9840a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    const uint32_t flags = hw.getFlags();
98553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian    const int32_t height = hw.getHeight();
9860656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian    if (mSwapRegion.isEmpty()) {
98753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian        return;
98853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian    }
9890a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
9900a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    if (!((flags & DisplayHardware::SWAP_RECTANGLE) ||
9910a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian            (flags & DisplayHardware::BUFFER_PRESERVED))) {
9920a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        const Region repaint((flags & DisplayHardware::PARTIAL_UPDATES) ?
9930a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian                mDirtyRegion.bounds() : hw.bounds());
9940a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        composeSurfaces(repaint);
9950a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    }
9960a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
997c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_EXTERNAL_OES);
998c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_2D);
999edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_BLEND);
1000edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_SCISSOR_TEST);
1001edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
10020926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    static int toggle = 0;
10030926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    toggle = 1 - toggle;
10040926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    if (toggle) {
10050a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        glColor4f(1, 0, 1, 1);
10060926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    } else {
10070a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        glColor4f(1, 1, 0, 1);
10080926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    }
1009edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
101020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    Region::const_iterator it = mDirtyRegion.begin();
101120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    Region::const_iterator const end = mDirtyRegion.end();
101220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    while (it != end) {
101320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        const Rect& r = *it++;
1014edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLfloat vertices[][2] = {
101553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.left,  height - r.top },
101653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.left,  height - r.bottom },
101753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.right, height - r.bottom },
101853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.right, height - r.top }
1019edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        };
1020edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glVertexPointer(2, GL_FLOAT, 0, vertices);
1021edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1022edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
10230a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
10240656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian    hw.flip(mSwapRegion);
1025edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1026edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mDebugRegion > 1)
10270a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        usleep(mDebugRegion * 1000);
1028edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1029edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glEnable(GL_SCISSOR_TEST);
1030edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1031edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1032edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::drawWormhole() const
1033edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1034edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Region region(mWormholeRegion.intersect(mDirtyRegion));
1035edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (region.isEmpty())
1036edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1037edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1038edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw(graphicPlane(0).displayHardware());
1039edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int32_t width = hw.getWidth();
1040edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int32_t height = hw.getHeight();
1041edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1042edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (LIKELY(!mDebugBackground)) {
10430a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        glClearColor(0,0,0,0);
104420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        Region::const_iterator it = region.begin();
104520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        Region::const_iterator const end = region.end();
104620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        while (it != end) {
104720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            const Rect& r = *it++;
1048edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const GLint sy = height - (r.top + r.height());
1049edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glScissor(r.left, sy, r.width(), r.height());
1050edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glClear(GL_COLOR_BUFFER_BIT);
1051edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1052edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
1053edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GLshort vertices[][2] = { { 0, 0 }, { width, 0 },
1054edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                { width, height }, { 0, height }  };
1055edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GLshort tcoords[][2] = { { 0, 0 }, { 1, 0 },  { 1, 1 }, { 0, 1 } };
1056c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian
1057edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glVertexPointer(2, GL_SHORT, 0, vertices);
1058edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glTexCoordPointer(2, GL_SHORT, 0, tcoords);
1059edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
1060c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian
1061c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian        glDisable(GL_TEXTURE_EXTERNAL_OES);
1062edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glEnable(GL_TEXTURE_2D);
1063edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glBindTexture(GL_TEXTURE_2D, mWormholeTexName);
1064edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1065edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glMatrixMode(GL_TEXTURE);
1066edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glLoadIdentity();
1067c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian
1068c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian        glDisable(GL_BLEND);
1069c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian
1070edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glScalef(width*(1.0f/32.0f), height*(1.0f/32.0f), 1);
107120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        Region::const_iterator it = region.begin();
107220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        Region::const_iterator const end = region.end();
107320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        while (it != end) {
107420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            const Rect& r = *it++;
1075edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const GLint sy = height - (r.top + r.height());
1076edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glScissor(r.left, sy, r.width(), r.height());
1077edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1078edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1079edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1080a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        glDisable(GL_TEXTURE_2D);
1081ebeb7095961e09f5cff0c7cf2c04fa4770b2e033Mathias Agopian        glLoadIdentity();
1082ebeb7095961e09f5cff0c7cf2c04fa4770b2e033Mathias Agopian        glMatrixMode(GL_MODELVIEW);
1083edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1084edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1085edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1086edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::debugShowFPS() const
1087edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1088edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    static int mFrameCount;
1089edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    static int mLastFrameCount = 0;
1090edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    static nsecs_t mLastFpsTime = 0;
1091edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    static float mFps = 0;
1092edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mFrameCount++;
1093edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    nsecs_t now = systemTime();
1094edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    nsecs_t diff = now - mLastFpsTime;
1095edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (diff > ms2ns(250)) {
1096edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mFps =  ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff;
1097edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mLastFpsTime = now;
1098edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mLastFrameCount = mFrameCount;
1099edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // XXX: mFPS has the value we want
1101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project }
1102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1103076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::addLayer(const sp<LayerBase>& layer)
1104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
1106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    addLayer_l(layer);
1107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
1108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1111076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::addLayer_l(const sp<LayerBase>& layer)
1112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1113f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian    ssize_t i = mCurrentState.layersSortedByZ.add(layer);
11141b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    return (i < 0) ? status_t(i) : status_t(NO_ERROR);
11151b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian}
11161b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
111796f0819f81293076e652792794a961543e6750d7Mathias Agopianssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
111896f0819f81293076e652792794a961543e6750d7Mathias Agopian        const sp<LayerBaseClient>& lbc)
11191b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
112096f0819f81293076e652792794a961543e6750d7Mathias Agopian    // attach this layer to the client
11214f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    size_t name = client->attachLayer(lbc);
11224f113740180b6512b43723c4728f262882dc9b45Mathias Agopian
11234f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    Mutex::Autolock _l(mStateLock);
112496f0819f81293076e652792794a961543e6750d7Mathias Agopian
112596f0819f81293076e652792794a961543e6750d7Mathias Agopian    // add this layer to the current state list
112696f0819f81293076e652792794a961543e6750d7Mathias Agopian    addLayer_l(lbc);
112796f0819f81293076e652792794a961543e6750d7Mathias Agopian
11284f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    return ssize_t(name);
112996f0819f81293076e652792794a961543e6750d7Mathias Agopian}
113096f0819f81293076e652792794a961543e6750d7Mathias Agopian
113196f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer)
113296f0819f81293076e652792794a961543e6750d7Mathias Agopian{
113396f0819f81293076e652792794a961543e6750d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
113496f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = purgatorizeLayer_l(layer);
113596f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR)
113696f0819f81293076e652792794a961543e6750d7Mathias Agopian        setTransactionFlags(eTransactionNeeded);
113796f0819f81293076e652792794a961543e6750d7Mathias Agopian    return err;
1138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1140076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase)
1141edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1142b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<LayerBaseClient> lbc(layerBase->getLayerBaseClient());
1143b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (lbc != 0) {
11440d1561275e80073807ac04728951782d943f8882Mathias Agopian        mLayerMap.removeItem( lbc->getSurfaceBinder() );
1145b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    }
1146edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase);
1147edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (index >= 0) {
1148076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved = true;
1149edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
1150edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
11513d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    return status_t(index);
1152edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
11549a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase)
11559a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
115676cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    // First add the layer to the purgatory list, which makes sure it won't
115776cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    // go away, then remove it from the main list (through a transaction).
11589a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    ssize_t err = removeLayer_l(layerBase);
115976cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    if (err >= 0) {
116076cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian        mLayerPurgatory.add(layerBase);
116176cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    }
11628c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian
11630b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian    layerBase->onRemoved();
11640b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian
11653d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // it's possible that we don't find a layer, because it might
11663d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // have been destroyed already -- this is not technically an error
116796f0819f81293076e652792794a961543e6750d7Mathias Agopian    // from the user because there is a race between Client::destroySurface(),
116896f0819f81293076e652792794a961543e6750d7Mathias Agopian    // ~Client() and ~ISurface().
11699a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err;
11709a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
11719a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
117296f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::invalidateLayerVisibility(const sp<LayerBase>& layer)
1173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
117496f0819f81293076e652792794a961543e6750d7Mathias Agopian    layer->forceVisibilityTransaction();
117596f0819f81293076e652792794a961543e6750d7Mathias Agopian    setTransactionFlags(eTraversalNeeded);
117696f0819f81293076e652792794a961543e6750d7Mathias Agopian    return NO_ERROR;
1177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1179dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopianuint32_t SurfaceFlinger::peekTransactionFlags(uint32_t flags)
1180dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian{
1181dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian    return android_atomic_release_load(&mTransactionFlags);
1182dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian}
1183dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian
1184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags)
1185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return android_atomic_and(~flags, &mTransactionFlags) & flags;
1187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1189bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags)
1190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t old = android_atomic_or(flags, &mTransactionFlags);
1192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((old & flags)==0) { // wake the server up
1193bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        signalEvent();
1194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1195edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return old;
1196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1199b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennisvoid SurfaceFlinger::setTransactionState(const Vector<ComposerState>& state,
120028378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        int orientation, uint32_t flags) {
1201698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
1202cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
120328378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    uint32_t transactionFlags = 0;
1204b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis    if (mCurrentState.orientation != orientation) {
1205b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis        if (uint32_t(orientation)<=eOrientation270 || orientation==42) {
1206b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis            mCurrentState.orientation = orientation;
120728378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis            transactionFlags |= eTransactionNeeded;
1208b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis        } else if (orientation != eOrientationUnchanged) {
1209b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis            LOGW("setTransactionState: ignoring unrecognized orientation: %d",
1210b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis                    orientation);
1211b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis        }
1212b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis    }
1213b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis
1214698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    const size_t count = state.size();
1215698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
1216698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const ComposerState& s(state[i]);
1217698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        sp<Client> client( static_cast<Client *>(s.client.get()) );
121828378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        transactionFlags |= setClientStateLocked(client, s.state);
1219698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    }
122028378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    if (transactionFlags) {
122128378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        setTransactionFlags(transactionFlags);
1222698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    }
1223698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian
122428378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    // if this is a synchronous transaction, wait for it to take effect before
122528378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    // returning.
122628378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    if (flags & eSynchronous) {
122728378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        mTransationPending = true;
122828378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    }
122928378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    while (mTransationPending) {
1230698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
1231698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (CC_UNLIKELY(err != NO_ERROR)) {
1232698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            // just in case something goes wrong in SF, return to the
1233698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            // called after a few seconds.
1234698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            LOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!");
123528378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis            mTransationPending = false;
1236698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            break;
1237cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        }
1238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
12418b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huberint SurfaceFlinger::setOrientation(DisplayID dpy,
1242c08731e756868653d09d3e49b723706df3687070Mathias Agopian        int orientation, uint32_t flags)
1243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
1245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return BAD_VALUE;
1246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
1248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mCurrentState.orientation != orientation) {
1249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (uint32_t(orientation)<=eOrientation270 || orientation==42) {
125021230c6410bdab13cd2bd274da54b1e4061b6035Jeff Brown            mCurrentState.orientationFlags = flags;
1251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mCurrentState.orientation = orientation;
1252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            setTransactionFlags(eTransactionNeeded);
1253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mTransactionCV.wait(mStateLock);
1254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
1255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            orientation = BAD_VALUE;
1256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return orientation;
1259edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
12610ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopiansp<ISurface> SurfaceFlinger::createSurface(
12620ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        ISurfaceComposerClient::surface_data_t* params,
12630ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const String8& name,
12640ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const sp<Client>& client,
1265edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        DisplayID d, uint32_t w, uint32_t h, PixelFormat format,
1266edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t flags)
1267edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1268076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBaseClient> layer;
1269a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    sp<ISurface> surfaceHandle;
12706e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian
12716e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    if (int32_t(w|h) < 0) {
12726e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian        LOGE("createSurface() failed, w or h is negative (w=%d, h=%d)",
12736e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian                int(w), int(h));
12746e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian        return surfaceHandle;
12756e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    }
12768b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
1277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    //LOGD("createSurface for pid %d (%d x %d)", pid, w, h);
1278b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<Layer> normalLayer;
1279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (flags & eFXSurfaceMask) {
1280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceNormal:
1281a5529c8778c2f407f482fc12165aeb76c0f505c2Mathias Agopian            normalLayer = createNormalSurface(client, d, w, h, flags, format);
1282a5529c8778c2f407f482fc12165aeb76c0f505c2Mathias Agopian            layer = normalLayer;
1283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
1284edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceBlur:
12851293a8eb567fd63c072a6970fa9dcf37d076059fMathias Agopian            // for now we treat Blur as Dim, until we can implement it
12861293a8eb567fd63c072a6970fa9dcf37d076059fMathias Agopian            // efficiently.
1287edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceDim:
128896f0819f81293076e652792794a961543e6750d7Mathias Agopian            layer = createDimSurface(client, d, w, h, flags);
1289edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
1290118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        case eFXSurfaceScreenshot:
1291118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian            layer = createScreenshotSurface(client, d, w, h, flags);
1292118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian            break;
1293edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1294edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1295076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (layer != 0) {
129696f0819f81293076e652792794a961543e6750d7Mathias Agopian        layer->initStates(w, h, flags);
1297285dbde2e0cd0057be070ded3be8f5f453147edcMathias Agopian        layer->setName(name);
129896f0819f81293076e652792794a961543e6750d7Mathias Agopian        ssize_t token = addClientLayer(client, layer);
1299b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        surfaceHandle = layer->getSurface();
13018b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber        if (surfaceHandle != 0) {
130296f0819f81293076e652792794a961543e6750d7Mathias Agopian            params->token = token;
1303a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            params->identity = layer->getIdentity();
1304b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            if (normalLayer != 0) {
1305b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian                Mutex::Autolock _l(mStateLock);
1306a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                mLayerMap.add(layer->getSurfaceBinder(), normalLayer);
1307b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            }
13081c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        }
1309b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
131096f0819f81293076e652792794a961543e6750d7Mathias Agopian        setTransactionFlags(eTransactionNeeded);
1311edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1312edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1313edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return surfaceHandle;
1314edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1315edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1316b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<Layer> SurfaceFlinger::createNormalSurface(
1317f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        const sp<Client>& client, DisplayID display,
131896f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags,
13191c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        PixelFormat& format)
1320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize the surfaces
1322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (format) { // TODO: take h/w into account
1323edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSPARENT:
1324edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSLUCENT:
1325edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        format = PIXEL_FORMAT_RGBA_8888;
1326edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1327edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_OPAQUE:
1328a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888
1329a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian        format = PIXEL_FORMAT_RGB_565;
1330a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#else
13318f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian        format = PIXEL_FORMAT_RGBX_8888;
1332a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif
1333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1334edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1335edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1336a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888
1337a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian    if (format == PIXEL_FORMAT_RGBX_8888)
1338a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian        format = PIXEL_FORMAT_RGBA_8888;
1339a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif
1340a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian
134196f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<Layer> layer = new Layer(this, display, client);
1342f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian    status_t err = layer->setBuffers(w, h, format, flags);
134396f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (LIKELY(err != NO_ERROR)) {
1344edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        LOGE("createNormalSurfaceLocked() failed (%s)", strerror(-err));
1345076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        layer.clear();
1346edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1347edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1348edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1349edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1350b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<LayerDim> SurfaceFlinger::createDimSurface(
1351f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        const sp<Client>& client, DisplayID display,
135296f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags)
1353edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
135496f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<LayerDim> layer = new LayerDim(this, display, client);
1355118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    return layer;
1356118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
1357118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
1358118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopiansp<LayerScreenshot> SurfaceFlinger::createScreenshotSurface(
1359118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        const sp<Client>& client, DisplayID display,
1360118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags)
1361118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{
1362118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    sp<LayerScreenshot> layer = new LayerScreenshot(this, display, client);
1363118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    status_t err = layer->capture();
1364118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    if (err != NO_ERROR) {
1365118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        layer.clear();
1366118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        LOGW("createScreenshotSurface failed (%s)", strerror(-err));
1367118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    }
1368edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1369edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1370edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
137196f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeSurface(const sp<Client>& client, SurfaceID sid)
13729a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
13739a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    /*
13749a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     * called by the window manager, when a surface should be marked for
13759a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     * destruction.
13768b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber     *
13770aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * The surface is removed from the current and drawing lists, but placed
13780aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * in the purgatory queue, so it's not destroyed right-away (we need
13790aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * to wait for all client's references to go away first).
13809a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     */
13819a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
138248d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    status_t err = NAME_NOT_FOUND;
13830aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian    Mutex::Autolock _l(mStateLock);
138496f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<LayerBaseClient> layer = client->getLayerUser(sid);
138548d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    if (layer != 0) {
138648d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        err = purgatorizeLayer_l(layer);
138748d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        if (err == NO_ERROR) {
138848d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian            setTransactionFlags(eTransactionNeeded);
138948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        }
13909a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    }
13919a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return err;
13929a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
13939a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
1394ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopianstatus_t SurfaceFlinger::destroySurface(const wp<LayerBaseClient>& layer)
1395edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1396759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian    // called by ~ISurface() when all references are gone
1397ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    status_t err = NO_ERROR;
1398ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    sp<LayerBaseClient> l(layer.promote());
1399ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    if (l != NULL) {
1400ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        Mutex::Autolock _l(mStateLock);
1401ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        err = removeLayer_l(l);
1402ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        if (err == NAME_NOT_FOUND) {
1403ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // The surface wasn't in the current list, which means it was
1404ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // removed already, which means it is in the purgatory,
1405ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // and need to be removed from there.
1406ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            ssize_t idx = mLayerPurgatory.remove(l);
1407ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            LOGE_IF(idx < 0,
1408ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian                    "layer=%p is not in the purgatory list", l.get());
1409f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        }
1410ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        LOGE_IF(err<0 && err != NAME_NOT_FOUND,
1411ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian                "error removing layer=%p (%s)", l.get(), strerror(-err));
1412ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    }
1413ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    return err;
1414edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1415edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1416698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopianuint32_t SurfaceFlinger::setClientStateLocked(
141796f0819f81293076e652792794a961543e6750d7Mathias Agopian        const sp<Client>& client,
1418698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const layer_state_t& s)
1419edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1420edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t flags = 0;
1421698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    sp<LayerBaseClient> layer(client->getLayerUser(s.surface));
1422698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    if (layer != 0) {
1423698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const uint32_t what = s.what;
1424698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & ePositionChanged) {
1425698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setPosition(s.x, s.y))
1426698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1427698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1428698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eLayerChanged) {
1429698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
1430698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setLayer(s.z)) {
1431698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                mCurrentState.layersSortedByZ.removeAt(idx);
1432698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                mCurrentState.layersSortedByZ.add(layer);
1433698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                // we need traversal (state changed)
1434698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                // AND transaction (list changed)
1435698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTransactionNeeded|eTraversalNeeded;
1436edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1437698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1438698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eSizeChanged) {
1439698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setSize(s.w, s.h)) {
1440698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1441edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1442edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1443698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eAlphaChanged) {
1444698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f)))
1445698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1446698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1447698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eMatrixChanged) {
1448698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setMatrix(s.matrix))
1449698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1450698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1451698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eTransparentRegionChanged) {
1452698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setTransparentRegionHint(s.transparentRegion))
1453698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1454698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1455698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eVisibilityChanged) {
1456698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setFlags(s.flags, s.mask))
1457698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1458698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1459edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1460698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    return flags;
1461edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1462edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1463edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::screenReleased(int dpy)
1464edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1465edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // this may be called by a signal handler, we can't do too much in here
1466edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    android_atomic_or(eConsoleReleased, &mConsoleSignals);
1467edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    signalEvent();
1468edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1469edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1470edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::screenAcquired(int dpy)
1471edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1472edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // this may be called by a signal handler, we can't do too much in here
1473edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    android_atomic_or(eConsoleAcquired, &mConsoleSignals);
1474edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    signalEvent();
1475edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1476edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1477edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
1478edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
14791d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling    const size_t SIZE = 4096;
1480edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char buffer[SIZE];
1481edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    String8 result;
148299b49840d309727678b77403d6cc9f920111623fMathias Agopian
148399b49840d309727678b77403d6cc9f920111623fMathias Agopian    if (!PermissionCache::checkCallingPermission(sDump)) {
1484edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        snprintf(buffer, SIZE, "Permission Denial: "
1485edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                "can't dump SurfaceFlinger from pid=%d, uid=%d\n",
1486edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                IPCThreadState::self()->getCallingPid(),
1487edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                IPCThreadState::self()->getCallingUid());
1488edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        result.append(buffer);
1489edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
14909795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
14919795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // figure out if we're stuck somewhere
14929795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const nsecs_t now = systemTime();
14939795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const nsecs_t inSwapBuffers(mDebugInSwapBuffers);
14949795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const nsecs_t inTransaction(mDebugInTransaction);
14959795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0;
14969795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0;
14979795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
14989795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // Try to get the main lock, but don't insist if we can't
14999795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // (this would indicate SF is stuck, but we want to be able to
15009795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // print something in dumpsys).
15019795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        int retry = 3;
15029795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        while (mStateLock.tryLock()<0 && --retry>=0) {
15039795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            usleep(1000000);
15049795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
15059795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const bool locked(retry >= 0);
15069795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (!locked) {
15078b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber            snprintf(buffer, SIZE,
15089795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "SurfaceFlinger appears to be unresponsive, "
15099795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "dumping anyways (no locks held)\n");
15109795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            result.append(buffer);
15119795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
15129795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
151348b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        /*
151448b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian         * Dump the visible layer list
151548b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian         */
1516edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
1517edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const size_t count = currentLayers.size();
151848b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        snprintf(buffer, SIZE, "Visible layers (count = %d)\n", count);
151948b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        result.append(buffer);
1520edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (size_t i=0 ; i<count ; i++) {
15211b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            const sp<LayerBase>& layer(currentLayers[i]);
15221b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            layer->dump(result, buffer, SIZE);
15231b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            const Layer::State& s(layer->drawingState());
1524edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            s.transparentRegion.dump(result, "transparentRegion");
1525edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->transparentRegionScreen.dump(result, "transparentRegionScreen");
1526edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->visibleRegionScreen.dump(result, "visibleRegionScreen");
1527edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
15281b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
152948b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        /*
153048b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian         * Dump the layers in the purgatory
153148b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian         */
153248b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
153348b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        const size_t purgatorySize =  mLayerPurgatory.size();
153448b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        snprintf(buffer, SIZE, "Purgatory state (%d entries)\n", purgatorySize);
153548b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        result.append(buffer);
153648b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        for (size_t i=0 ; i<purgatorySize ; i++) {
153748b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian            const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
153848b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian            layer->shortDump(result, buffer, SIZE);
153948b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        }
154048b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
154148b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        /*
154248b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian         * Dump SurfaceFlinger global state
154348b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian         */
154448b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
1545ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian        snprintf(buffer, SIZE, "SurfaceFlinger global state:\n");
154648b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        result.append(buffer);
1547ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian
1548ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian        const GLExtensions& extensions(GLExtensions::getInstance());
1549ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian        snprintf(buffer, SIZE, "GLES: %s, %s, %s\n",
1550ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian                extensions.getVendor(),
1551ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian                extensions.getRenderer(),
1552ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian                extensions.getVersion());
1553ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian        result.append(buffer);
1554ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian        snprintf(buffer, SIZE, "EXTS: %s\n", extensions.getExtension());
1555ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian        result.append(buffer);
1556ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian
1557edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mWormholeRegion.dump(result, "WormholeRegion");
1558edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const DisplayHardware& hw(graphicPlane(0).displayHardware());
1559edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        snprintf(buffer, SIZE,
1560a402c4c9913cfbc6c3da21719c57a93a11f091f0Jamie Gennis                "  orientation=%d, canDraw=%d\n",
1561edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mCurrentState.orientation, hw.canDraw());
1562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        result.append(buffer);
15639795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        snprintf(buffer, SIZE,
15649795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                "  last eglSwapBuffers() time: %f us\n"
1565d5e4ef9e439317e2525a51106dbc509d3982de24Mathias Agopian                "  last transaction time     : %f us\n"
1566d5e4ef9e439317e2525a51106dbc509d3982de24Mathias Agopian                "  refresh-rate              : %f fps\n"
1567d5e4ef9e439317e2525a51106dbc509d3982de24Mathias Agopian                "  x-dpi                     : %f\n"
1568d5e4ef9e439317e2525a51106dbc509d3982de24Mathias Agopian                "  y-dpi                     : %f\n",
1569d5e4ef9e439317e2525a51106dbc509d3982de24Mathias Agopian                mLastSwapBufferTime/1000.0,
1570d5e4ef9e439317e2525a51106dbc509d3982de24Mathias Agopian                mLastTransactionTime/1000.0,
1571d5e4ef9e439317e2525a51106dbc509d3982de24Mathias Agopian                hw.getRefreshRate(),
1572d5e4ef9e439317e2525a51106dbc509d3982de24Mathias Agopian                hw.getDpiX(),
1573d5e4ef9e439317e2525a51106dbc509d3982de24Mathias Agopian                hw.getDpiY());
15749795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        result.append(buffer);
15751b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
15769795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (inSwapBuffersDuration || !locked) {
15779795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            snprintf(buffer, SIZE, "  eglSwapBuffers time: %f us\n",
15789795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    inSwapBuffersDuration/1000.0);
15799795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            result.append(buffer);
15809795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
15811b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
15829795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (inTransactionDuration || !locked) {
15839795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            snprintf(buffer, SIZE, "  transaction time: %f us\n",
15849795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    inTransactionDuration/1000.0);
15859795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            result.append(buffer);
15869795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
15871b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
158848b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        /*
158948b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian         * Dump HWComposer state
159048b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian         */
159173d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian        HWComposer& hwc(hw.getHwComposer());
159273d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian        snprintf(buffer, SIZE, "  h/w composer %s and %s\n",
159373d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian                hwc.initCheck()==NO_ERROR ? "present" : "not present",
159453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                (mDebugDisableHWC || mDebugRegion) ? "disabled" : "enabled");
159573d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian        result.append(buffer);
159622da60c3e64cd57535cbba063c07127814a2b52fMathias Agopian        hwc.dump(result, buffer, SIZE, mVisibleLayersSortedByZ);
159773d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian
159848b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        /*
159948b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian         * Dump gralloc state
160048b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian         */
16013330b203039dea366d4981db1408a460134b2d2cMathias Agopian        const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
1602076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        alloc.dump(result);
16031d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling        hw.dump(result);
16049795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
16059795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (locked) {
16069795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            mStateLock.unlock();
16079795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
1608edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1609edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    write(fd, result.string(), result.size());
1610edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1611edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1612edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1613edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::onTransact(
1614edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
1615edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1616edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (code) {
1617edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case CREATE_CONNECTION:
1618698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        case SET_TRANSACTION_STATE:
1619edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case SET_ORIENTATION:
1620edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case BOOT_FINISHED:
162159119e658a12279e8fff508f8773843de2d90917Mathias Agopian        case TURN_ELECTRON_BEAM_OFF:
16229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        case TURN_ELECTRON_BEAM_ON:
1623edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        {
1624edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // codes that require permission check
1625edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            IPCThreadState* ipc = IPCThreadState::self();
1626edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int pid = ipc->getCallingPid();
1627a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian            const int uid = ipc->getCallingUid();
162899b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
162999b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) {
1630375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                LOGE("Permission Denial: "
1631375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                        "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
1632375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                return PERMISSION_DENIED;
1633edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
16341b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
16351b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
16361b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        case CAPTURE_SCREEN:
16371b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
16381b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            // codes that require permission check
16391b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
16401b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int pid = ipc->getCallingPid();
16411b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int uid = ipc->getCallingUid();
164299b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
164399b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) {
16441b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                LOGE("Permission Denial: "
16451b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                        "can't read framebuffer pid=%d, uid=%d", pid, uid);
16461b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                return PERMISSION_DENIED;
16471b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            }
16481b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
1649edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1650edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
16511b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
1652edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
1653edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
1654b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        CHECK_INTERFACE(ISurfaceComposer, data, reply);
165599b49840d309727678b77403d6cc9f920111623fMathias Agopian        if (UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) {
1656375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
1657375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int pid = ipc->getCallingPid();
1658375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int uid = ipc->getCallingUid();
1659375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            LOGE("Permission Denial: "
1660375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                    "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
1661edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return PERMISSION_DENIED;
1662edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1663edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int n;
1664edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        switch (code) {
166501b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian            case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE
166635b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian            case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE
1667edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1668edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1002:  // SHOW_UPDATES
1669edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                n = data.readInt32();
1670edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDebugRegion = n ? n : (mDebugRegion ? 0 : 1);
167153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
167253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
1673edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1674edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1003:  // SHOW_BACKGROUND
1675edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                n = data.readInt32();
1676edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDebugBackground = n ? 1 : 0;
1677edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1678edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1004:{ // repaint everything
167953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
1680cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
1681cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            }
1682cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            case 1005:{ // force transaction
1683cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
1684cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
1685edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
168635b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian            case 1006:{ // enable/disable GraphicLog
168735b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian                int enabled = data.readInt32();
168835b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian                GraphicLog::getInstance().setEnabled(enabled);
168935b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian                return NO_ERROR;
169035b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian            }
169153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian            case 1008:  // toggle use of hw composer
169253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                n = data.readInt32();
169353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                mDebugDisableHWC = n ? 1 : 0;
169453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
169553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
169653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                return NO_ERROR;
1697a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian            case 1009:  // toggle use of transform hint
1698a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                n = data.readInt32();
1699a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                mDebugDisableTransformHint = n ? 1 : 0;
1700a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                invalidateHwcGeometry();
1701a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                repaintEverything();
1702a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                return NO_ERROR;
1703edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1010:  // interrogate.
170401b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian                reply->writeInt32(0);
1705edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(0);
1706edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(mDebugRegion);
1707edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(mDebugBackground);
1708edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1709edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1013: {
1710edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                Mutex::Autolock _l(mStateLock);
1711edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                const DisplayHardware& hw(graphicPlane(0).displayHardware());
1712edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(hw.getPageFlipCount());
1713edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1714edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return NO_ERROR;
1715edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1716edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1717edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return err;
1718edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1719edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
172053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopianvoid SurfaceFlinger::repaintEverything() {
172153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
17220dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    const Rect bounds(hw.getBounds());
17230dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    setInvalidateRegion(Region(bounds));
172453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian    signalEvent();
172553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian}
172653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian
17270dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopianvoid SurfaceFlinger::setInvalidateRegion(const Region& reg) {
17280dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    Mutex::Autolock _l(mInvalidateLock);
17290dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    mInvalidateRegion = reg;
17300dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian}
17310dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian
17320dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias AgopianRegion SurfaceFlinger::getAndClearInvalidateRegion() {
17330dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    Mutex::Autolock _l(mInvalidateLock);
17340dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    Region reg(mInvalidateRegion);
17350dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    mInvalidateRegion.clear();
17360dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    return reg;
17370dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian}
17380dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian
173959119e658a12279e8fff508f8773843de2d90917Mathias Agopian// ---------------------------------------------------------------------------
174059119e658a12279e8fff508f8773843de2d90917Mathias Agopian
1741118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopianstatus_t SurfaceFlinger::renderScreenToTexture(DisplayID dpy,
1742118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        GLuint* textureName, GLfloat* uOut, GLfloat* vOut)
1743118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{
1744118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    Mutex::Autolock _l(mStateLock);
1745118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    return renderScreenToTextureLocked(dpy, textureName, uOut, vOut);
1746118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
1747118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
17489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::renderScreenToTextureLocked(DisplayID dpy,
17499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        GLuint* textureName, GLfloat* uOut, GLfloat* vOut)
175059119e658a12279e8fff508f8773843de2d90917Mathias Agopian{
175159119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
175259119e658a12279e8fff508f8773843de2d90917Mathias Agopian        return INVALID_OPERATION;
175359119e658a12279e8fff508f8773843de2d90917Mathias Agopian
175459119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // get screen geometry
175559119e658a12279e8fff508f8773843de2d90917Mathias Agopian    const DisplayHardware& hw(graphicPlane(dpy).displayHardware());
175659119e658a12279e8fff508f8773843de2d90917Mathias Agopian    const uint32_t hw_w = hw.getWidth();
175759119e658a12279e8fff508f8773843de2d90917Mathias Agopian    const uint32_t hw_h = hw.getHeight();
175859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLfloat u = 1;
175959119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLfloat v = 1;
176059119e658a12279e8fff508f8773843de2d90917Mathias Agopian
176159119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // make sure to clear all GL error flags
176259119e658a12279e8fff508f8773843de2d90917Mathias Agopian    while ( glGetError() != GL_NO_ERROR ) ;
176359119e658a12279e8fff508f8773843de2d90917Mathias Agopian
176459119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // create a FBO
176559119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLuint name, tname;
176659119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glGenTextures(1, &tname);
176759119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
17689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
17699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            hw_w, hw_h, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
177059119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (glGetError() != GL_NO_ERROR) {
1771015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian        while ( glGetError() != GL_NO_ERROR ) ;
177259119e658a12279e8fff508f8773843de2d90917Mathias Agopian        GLint tw = (2 << (31 - clz(hw_w)));
177359119e658a12279e8fff508f8773843de2d90917Mathias Agopian        GLint th = (2 << (31 - clz(hw_h)));
17749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
17759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian                tw, th, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
177659119e658a12279e8fff508f8773843de2d90917Mathias Agopian        u = GLfloat(hw_w) / tw;
177759119e658a12279e8fff508f8773843de2d90917Mathias Agopian        v = GLfloat(hw_h) / th;
177859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    }
177959119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glGenFramebuffersOES(1, &name);
178059119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
17819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES,
17829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0);
178359119e658a12279e8fff508f8773843de2d90917Mathias Agopian
17849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // redraw the screen entirely...
1785c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_EXTERNAL_OES);
1786c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_2D);
178762f7114719d2009dca7dd120f0fe29a24bd77a40Mathias Agopian    glDisable(GL_SCISSOR_TEST);
17889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glClearColor(0,0,0,1);
17899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glClear(GL_COLOR_BUFFER_BIT);
179062f7114719d2009dca7dd120f0fe29a24bd77a40Mathias Agopian    glEnable(GL_SCISSOR_TEST);
1791a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glMatrixMode(GL_MODELVIEW);
1792a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glLoadIdentity();
17939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
17949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const size_t count = layers.size();
17959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (size_t i=0 ; i<count ; ++i) {
17969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
17979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        layer->drawForSreenShot();
17989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
179959119e658a12279e8fff508f8773843de2d90917Mathias Agopian
1800118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    hw.compositionComplete();
1801118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
18029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // back to main framebuffer
18039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
18049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_SCISSOR_TEST);
18059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDeleteFramebuffersOES(1, &name);
180659119e658a12279e8fff508f8773843de2d90917Mathias Agopian
18079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *textureName = tname;
18089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *uOut = u;
18099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *vOut = v;
18109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
18119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
181259119e658a12279e8fff508f8773843de2d90917Mathias Agopian
18139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// ---------------------------------------------------------------------------
181459119e658a12279e8fff508f8773843de2d90917Mathias Agopian
18159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::electronBeamOffAnimationImplLocked()
18169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
18179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // get screen geometry
18189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
18199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_w = hw.getWidth();
18209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_h = hw.getHeight();
1821a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    const Region screenBounds(hw.getBounds());
182259119e658a12279e8fff508f8773843de2d90917Mathias Agopian
18239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat u, v;
18249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLuint tname;
1825118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    status_t result = renderScreenToTextureLocked(0, &tname, &u, &v);
18269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (result != NO_ERROR) {
18279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return result;
18289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
182959119e658a12279e8fff508f8773843de2d90917Mathias Agopian
18309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat vtx[8];
1831a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    const GLfloat texCoords[4][2] = { {0,0}, {0,v}, {u,v}, {u,0} };
18329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
18339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
18349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
18359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
18369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
18379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
18389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glVertexPointer(2, GL_FLOAT, 0, vtx);
18399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
1840ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    /*
1841ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     * Texture coordinate mapping
1842ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *
1843ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *                 u
1844ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *    1 +----------+---+
1845ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |     |    |   |  image is inverted
1846ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |     V    |   |  w.r.t. the texture
1847ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *  1-v +----------+   |  coordinates
1848ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |              |
1849ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |              |
1850ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |              |
1851ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *    0 +--------------+
1852ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      0              1
1853ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *
1854ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     */
1855ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian
18569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class s_curve_interpolator {
18579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float nbFrames, s, v;
18589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
18599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        s_curve_interpolator(int nbFrames, float s)
18609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : nbFrames(1.0f / (nbFrames-1)), s(s),
18619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian          v(1.0f + expf(-s + 0.5f*s)) {
18629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
18639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float operator()(int f) {
18649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const float x = f * nbFrames;
18659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f;
18669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
18679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
18689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
18699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class v_stretch {
18709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
18719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
18729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        v_stretch(uint32_t hw_w, uint32_t hw_h)
18739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
18749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
18759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
18769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w + (hw_w * v);
18779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = hw_h - (hw_h * v);
18789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
18799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
1880ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[0] = x;         vtx[1] = y;
1881ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
1882ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
1883ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
18849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
18859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
18869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
18879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class h_stretch {
18889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
18899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
18909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        h_stretch(uint32_t hw_w, uint32_t hw_h)
18919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
189259119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
18939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
18949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w - (hw_w * v);
18959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = 1.0f;
18969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
18979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
1898ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[0] = x;         vtx[1] = y;
1899ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
1900ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
1901ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
19029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
19039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
19049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // the full animation is 24 frames
1906ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    char value[PROPERTY_VALUE_MAX];
1907ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    property_get("debug.sf.electron_frames", value, "24");
1908ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    int nbFrames = (atoi(value) + 1) >> 1;
1909ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    if (nbFrames <= 0) // just in case
1910ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian        nbFrames = 24;
1911ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian
19129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itr(nbFrames, 7.5f);
19139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itg(nbFrames, 8.0f);
19149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itb(nbFrames, 8.5f);
19159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    v_stretch vverts(hw_w, hw_h);
1917a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian
1918a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glMatrixMode(GL_TEXTURE);
1919a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glLoadIdentity();
1920a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glMatrixMode(GL_MODELVIEW);
1921a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glLoadIdentity();
1922a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian
19239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnable(GL_BLEND);
19249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBlendFunc(GL_ONE, GL_ONE);
19259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=0 ; i<nbFrames ; i++) {
19269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float x, y, w, h;
19279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vr = itr(i);
19289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vg = itg(i);
19299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vb = itb(i);
19309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // clear screen
19329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(1,1,1,1);
19339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
19349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glEnable(GL_TEXTURE_2D);
193559119e658a12279e8fff508f8773843de2d90917Mathias Agopian
19369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the red plane
19379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vr);
19389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(1,0,0,1);
19399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
19409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the green plane
19429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vg);
19439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,1,0,1);
19449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
19459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the blue plane
19479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vb);
19489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,0,1,1);
19499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
19509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the white highlight (we use the last vertices)
195259119e658a12279e8fff508f8773843de2d90917Mathias Agopian        glDisable(GL_TEXTURE_2D);
195359119e658a12279e8fff508f8773843de2d90917Mathias Agopian        glColorMask(1,1,1,1);
19549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColor4f(vg, vg, vg, 1);
19559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
19569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
19579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
19589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    h_stretch hverts(hw_w, hw_h);
19609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_BLEND);
19619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_TEXTURE_2D);
19629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
19639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=0 ; i<nbFrames ; i++) {
19649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float v = itg(i);
19659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hverts(vtx, v);
19669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
19679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColor4f(1-v, 1-v, 1-v, 1);
19689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
19699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
19709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
19719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
19739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnable(GL_SCISSOR_TEST);
19749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
19759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDeleteTextures(1, &tname);
1976a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    glDisable(GL_TEXTURE_2D);
1977c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_BLEND);
19789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
19799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
19809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::electronBeamOnAnimationImplLocked()
19829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
19839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    status_t result = PERMISSION_DENIED;
19849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
19869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return INVALID_OPERATION;
19879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // get screen geometry
19909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
19919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_w = hw.getWidth();
19929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_h = hw.getHeight();
19939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const Region screenBounds(hw.bounds());
19949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat u, v;
19969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLuint tname;
19979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    result = renderScreenToTextureLocked(0, &tname, &u, &v);
19989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (result != NO_ERROR) {
19999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return result;
20009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
20019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat vtx[8];
20039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const GLfloat texCoords[4][2] = { {0,v}, {0,0}, {u,0}, {u,v} };
20049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
20059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
20069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
20079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
20089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
20099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
20109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glVertexPointer(2, GL_FLOAT, 0, vtx);
20119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class s_curve_interpolator {
20139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float nbFrames, s, v;
20149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
20159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        s_curve_interpolator(int nbFrames, float s)
20169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : nbFrames(1.0f / (nbFrames-1)), s(s),
20179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian          v(1.0f + expf(-s + 0.5f*s)) {
20189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
20199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float operator()(int f) {
20209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const float x = f * nbFrames;
20219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f;
20229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
20239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
20249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class v_stretch {
20269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
20279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
20289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        v_stretch(uint32_t hw_w, uint32_t hw_h)
20299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
203059119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
20319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
20329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w + (hw_w * v);
20339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = hw_h - (hw_h * v);
20349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
20359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
20369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[0] = x;         vtx[1] = y;
20379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
20389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
20399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
20409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
20419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
20429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class h_stretch {
20449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
20459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
20469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        h_stretch(uint32_t hw_w, uint32_t hw_h)
20479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
20489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
20499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
20509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w - (hw_w * v);
20519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = 1.0f;
20529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
20539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
20549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[0] = x;         vtx[1] = y;
20559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
20569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
20579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
20589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
20599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
20609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2061a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian    // the full animation is 12 frames
2062a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian    int nbFrames = 8;
20639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itr(nbFrames, 7.5f);
20649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itg(nbFrames, 8.0f);
20659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itb(nbFrames, 8.5f);
20669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    h_stretch hverts(hw_w, hw_h);
20689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_BLEND);
20699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_TEXTURE_2D);
20709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
20719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=nbFrames-1 ; i>=0 ; i--) {
20729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float v = itg(i);
20739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hverts(vtx, v);
20749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
20759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColor4f(1-v, 1-v, 1-v, 1);
20769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
20779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
20789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
20799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2080a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian    nbFrames = 4;
20819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    v_stretch vverts(hw_w, hw_h);
20829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnable(GL_BLEND);
20839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBlendFunc(GL_ONE, GL_ONE);
20849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=nbFrames-1 ; i>=0 ; i--) {
20859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float x, y, w, h;
20869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vr = itr(i);
20879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vg = itg(i);
20889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vb = itb(i);
208959119e658a12279e8fff508f8773843de2d90917Mathias Agopian
20909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // clear screen
209159119e658a12279e8fff508f8773843de2d90917Mathias Agopian        glColorMask(1,1,1,1);
20929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
20939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glEnable(GL_TEXTURE_2D);
20949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the red plane
20969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vr);
20979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(1,0,0,1);
20989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
20999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the green plane
21019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vg);
21029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,1,0,1);
21039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
21049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the blue plane
21069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vb);
21079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,0,1,1);
21089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
21099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
211159119e658a12279e8fff508f8773843de2d90917Mathias Agopian    }
211259119e658a12279e8fff508f8773843de2d90917Mathias Agopian
21139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
21149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnable(GL_SCISSOR_TEST);
21159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
211659119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glDeleteTextures(1, &tname);
2117a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    glDisable(GL_TEXTURE_2D);
2118c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_BLEND);
211959119e658a12279e8fff508f8773843de2d90917Mathias Agopian
21209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
21219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
21229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// ---------------------------------------------------------------------------
21249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2125abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOffImplLocked(int32_t mode)
21269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
21279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    DisplayHardware& hw(graphicPlane(0).editDisplayHardware());
21289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (!hw.canDraw()) {
21299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // we're already off
21309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return NO_ERROR;
21319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
21327ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian
21337ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian    // turn off hwc while we're doing the animation
21347ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian    hw.getHwComposer().disable();
21357ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian    // and make sure to turn it back on (if needed) next time we compose
21367ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian    invalidateHwcGeometry();
21377ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian
2138abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    if (mode & ISurfaceComposer::eElectronBeamAnimationOff) {
2139abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        electronBeamOffAnimationImplLocked();
2140abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    }
2141abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian
2142abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    // always clear the whole screen at the end of the animation
2143abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    glClearColor(0,0,0,1);
2144abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    glDisable(GL_SCISSOR_TEST);
2145abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    glClear(GL_COLOR_BUFFER_BIT);
2146abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    glEnable(GL_SCISSOR_TEST);
2147abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    hw.flip( Region(hw.bounds()) );
2148abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian
2149015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian    return NO_ERROR;
215059119e658a12279e8fff508f8773843de2d90917Mathias Agopian}
215159119e658a12279e8fff508f8773843de2d90917Mathias Agopian
215259119e658a12279e8fff508f8773843de2d90917Mathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOff(int32_t mode)
215359119e658a12279e8fff508f8773843de2d90917Mathias Agopian{
215459119e658a12279e8fff508f8773843de2d90917Mathias Agopian    class MessageTurnElectronBeamOff : public MessageBase {
215559119e658a12279e8fff508f8773843de2d90917Mathias Agopian        SurfaceFlinger* flinger;
2156abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        int32_t mode;
215759119e658a12279e8fff508f8773843de2d90917Mathias Agopian        status_t result;
215859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    public:
2159abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        MessageTurnElectronBeamOff(SurfaceFlinger* flinger, int32_t mode)
2160abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            : flinger(flinger), mode(mode), result(PERMISSION_DENIED) {
216159119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
216259119e658a12279e8fff508f8773843de2d90917Mathias Agopian        status_t getResult() const {
216359119e658a12279e8fff508f8773843de2d90917Mathias Agopian            return result;
216459119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
216559119e658a12279e8fff508f8773843de2d90917Mathias Agopian        virtual bool handler() {
216659119e658a12279e8fff508f8773843de2d90917Mathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
2167abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            result = flinger->turnElectronBeamOffImplLocked(mode);
216859119e658a12279e8fff508f8773843de2d90917Mathias Agopian            return true;
216959119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
217059119e658a12279e8fff508f8773843de2d90917Mathias Agopian    };
217159119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2172abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    sp<MessageBase> msg = new MessageTurnElectronBeamOff(this, mode);
217359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    status_t res = postMessageSync(msg);
217459119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (res == NO_ERROR) {
217559119e658a12279e8fff508f8773843de2d90917Mathias Agopian        res = static_cast<MessageTurnElectronBeamOff*>( msg.get() )->getResult();
21769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // work-around: when the power-manager calls us we activate the
21789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // animation. eventually, the "on" animation will be called
21799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // by the power-manager itself
2180abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        mElectronBeamAnimationMode = mode;
218159119e658a12279e8fff508f8773843de2d90917Mathias Agopian    }
218259119e658a12279e8fff508f8773843de2d90917Mathias Agopian    return res;
218359119e658a12279e8fff508f8773843de2d90917Mathias Agopian}
218459119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
2186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2187abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOnImplLocked(int32_t mode)
21889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
21899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    DisplayHardware& hw(graphicPlane(0).editDisplayHardware());
21909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (hw.canDraw()) {
21919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // we're already on
21929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return NO_ERROR;
21939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
2194abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    if (mode & ISurfaceComposer::eElectronBeamAnimationOn) {
2195abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        electronBeamOnAnimationImplLocked();
2196abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    }
2197a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian
2198a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian    // make sure to redraw the whole screen when the animation is done
2199a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian    mDirtyRegion.set(hw.bounds());
2200a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian    signalEvent();
2201a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian
2202015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian    return NO_ERROR;
22039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
22049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOn(int32_t mode)
22069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
22079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class MessageTurnElectronBeamOn : public MessageBase {
22089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        SurfaceFlinger* flinger;
2209abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        int32_t mode;
22109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        status_t result;
22119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
2212abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        MessageTurnElectronBeamOn(SurfaceFlinger* flinger, int32_t mode)
2213abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            : flinger(flinger), mode(mode), result(PERMISSION_DENIED) {
22149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
22159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        status_t getResult() const {
22169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return result;
22179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
22189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        virtual bool handler() {
22199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
2220abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            result = flinger->turnElectronBeamOnImplLocked(mode);
22219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return true;
22229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
22239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
22249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2225abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    postMessageAsync( new MessageTurnElectronBeamOn(this, mode) );
22269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
22279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
22289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// ---------------------------------------------------------------------------
22309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
223174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopianstatus_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy,
223274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        sp<IMemoryHeap>* heap,
223374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t* w, uint32_t* h, PixelFormat* f,
2234bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t sw, uint32_t sh,
2235bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ, uint32_t maxLayerZ)
223674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{
223774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    status_t result = PERMISSION_DENIED;
223874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
223974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // only one display supported for now
224074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
224174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return BAD_VALUE;
224274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
224374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
224474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return INVALID_OPERATION;
224574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
224674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // get screen geometry
224774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const DisplayHardware& hw(graphicPlane(dpy).displayHardware());
224874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const uint32_t hw_w = hw.getWidth();
224974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const uint32_t hw_h = hw.getHeight();
225074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
225174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    if ((sw > hw_w) || (sh > hw_h))
225274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return BAD_VALUE;
225374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
225474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    sw = (!sw) ? hw_w : sw;
225574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    sh = (!sh) ? hw_h : sh;
225674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const size_t size = sw * sh * 4;
225774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
22581c71a47a6db679a3212f0c99e14f330d6da500faMathias Agopian    //LOGD("screenshot: sw=%d, sh=%d, minZ=%d, maxZ=%d",
22591c71a47a6db679a3212f0c99e14f330d6da500faMathias Agopian    //        sw, sh, minLayerZ, maxLayerZ);
2260c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
226174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // make sure to clear all GL error flags
226274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    while ( glGetError() != GL_NO_ERROR ) ;
226374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
226474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // create a FBO
226574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    GLuint name, tname;
226674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glGenRenderbuffersOES(1, &tname);
226774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindRenderbufferOES(GL_RENDERBUFFER_OES, tname);
226874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA8_OES, sw, sh);
226974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glGenFramebuffersOES(1, &name);
227074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
227174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES,
227274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, tname);
227374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
227474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
2275c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
227674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    if (status == GL_FRAMEBUFFER_COMPLETE_OES) {
227774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
227874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // invert everything, b/c glReadPixel() below will invert the FB
227974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glViewport(0, 0, sw, sh);
2280f653b897a449e10d6cbfb6e0812f7b0bb02d6482Mathias Agopian        glScissor(0, 0, sw, sh);
2281ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian        glEnable(GL_SCISSOR_TEST);
228274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_PROJECTION);
228374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glPushMatrix();
228474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glLoadIdentity();
2285ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian        glOrthof(0, hw_w, hw_h, 0, 0, 1);
228674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_MODELVIEW);
228774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
228874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // redraw the screen entirely...
228974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glClearColor(0,0,0,1);
229074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
2291f653b897a449e10d6cbfb6e0812f7b0bb02d6482Mathias Agopian
22929575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        const LayerVector& layers(mDrawingState.layersSortedByZ);
22939575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        const size_t count = layers.size();
229474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        for (size_t i=0 ; i<count ; ++i) {
229574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            const sp<LayerBase>& layer(layers[i]);
2296b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian            const uint32_t flags = layer->drawingState().flags;
2297b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian            if (!(flags & ISurfaceComposer::eLayerHidden)) {
2298b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                const uint32_t z = layer->drawingState().z;
2299b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                if (z >= minLayerZ && z <= maxLayerZ) {
2300b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                    layer->drawForSreenShot();
2301b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                }
2302bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian            }
230374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        }
230474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
230574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // XXX: this is needed on tegra
2306ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian        glEnable(GL_SCISSOR_TEST);
230774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glScissor(0, 0, sw, sh);
230874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
230974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // check for errors and return screen capture
231074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        if (glGetError() != GL_NO_ERROR) {
231174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // error while rendering
231274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            result = INVALID_OPERATION;
231374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        } else {
231474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // allocate shared memory large enough to hold the
231574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // screen capture
231674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            sp<MemoryHeapBase> base(
231774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    new MemoryHeapBase(size, 0, "screen-capture") );
231874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            void* const ptr = base->getBase();
231974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            if (ptr) {
232074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                // capture the screen with glReadPixels()
232174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                glReadPixels(0, 0, sw, sh, GL_RGBA, GL_UNSIGNED_BYTE, ptr);
232274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                if (glGetError() == GL_NO_ERROR) {
232374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *heap = base;
232474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *w = sw;
232574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *h = sh;
232674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *f = PIXEL_FORMAT_RGBA_8888;
232774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    result = NO_ERROR;
232874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                }
232974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            } else {
233074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                result = NO_MEMORY;
233174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            }
233274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        }
233374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glEnable(GL_SCISSOR_TEST);
233474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glViewport(0, 0, hw_w, hw_h);
233574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_PROJECTION);
233674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glPopMatrix();
233774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_MODELVIEW);
233874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    } else {
233974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        result = BAD_VALUE;
234074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    }
234174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
234274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // release FBO resources
234374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
234474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glDeleteRenderbuffersOES(1, &tname);
234574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glDeleteFramebuffersOES(1, &name);
2346e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian
2347e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian    hw.compositionComplete();
2348e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian
23491c71a47a6db679a3212f0c99e14f330d6da500faMathias Agopian    // LOGD("screenshot: result = %s", result<0 ? strerror(result) : "OK");
2350c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
235174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    return result;
235274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian}
235374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
235474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
23551b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopianstatus_t SurfaceFlinger::captureScreen(DisplayID dpy,
23561b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        sp<IMemoryHeap>* heap,
235774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t* width, uint32_t* height, PixelFormat* format,
2358bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t sw, uint32_t sh,
2359bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ, uint32_t maxLayerZ)
23601b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian{
23611b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    // only one display supported for now
23621b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
23631b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        return BAD_VALUE;
23641b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
23651b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
23661b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        return INVALID_OPERATION;
23671b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
23681b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    class MessageCaptureScreen : public MessageBase {
23691b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        SurfaceFlinger* flinger;
23701b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        DisplayID dpy;
23711b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        sp<IMemoryHeap>* heap;
23721b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        uint32_t* w;
23731b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        uint32_t* h;
23741b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        PixelFormat* f;
237574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t sw;
237674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t sh;
2377bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ;
2378bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t maxLayerZ;
23791b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        status_t result;
23801b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    public:
23811b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        MessageCaptureScreen(SurfaceFlinger* flinger, DisplayID dpy,
238274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                sp<IMemoryHeap>* heap, uint32_t* w, uint32_t* h, PixelFormat* f,
2383bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                uint32_t sw, uint32_t sh,
2384bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                uint32_t minLayerZ, uint32_t maxLayerZ)
23851b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            : flinger(flinger), dpy(dpy),
2386bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              heap(heap), w(w), h(h), f(f), sw(sw), sh(sh),
2387bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              minLayerZ(minLayerZ), maxLayerZ(maxLayerZ),
2388bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              result(PERMISSION_DENIED)
23891b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
23901b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
23911b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        status_t getResult() const {
23921b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            return result;
23931b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
23941b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        virtual bool handler() {
23951b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
23961b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
23971b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            // if we have secure windows, never allow the screen capture
23981b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            if (flinger->mSecureFrameBuffer)
23991b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                return true;
24001b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
240174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            result = flinger->captureScreenImplLocked(dpy,
2402bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                    heap, w, h, f, sw, sh, minLayerZ, maxLayerZ);
24031b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
24041b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            return true;
24051b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
24061b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    };
24071b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
24081b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    sp<MessageBase> msg = new MessageCaptureScreen(this,
2409bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian            dpy, heap, width, height, format, sw, sh, minLayerZ, maxLayerZ);
24101b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    status_t res = postMessageSync(msg);
24111b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    if (res == NO_ERROR) {
24121b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        res = static_cast<MessageCaptureScreen*>( msg.get() )->getResult();
24131b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    }
24141b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    return res;
24151b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian}
24161b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
24171b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// ---------------------------------------------------------------------------
24181b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
2419b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<Layer> SurfaceFlinger::getLayer(const sp<ISurface>& sur) const
2420edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2421b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<Layer> result;
2422b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    Mutex::Autolock _l(mStateLock);
2423b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    result = mLayerMap.valueFor( sur->asBinder() ).promote();
2424b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return result;
2425b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
24267303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
2427b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// ---------------------------------------------------------------------------
242896f0819f81293076e652792794a961543e6750d7Mathias Agopian
2429b7e930db175c192464cebdeb49eb56cf6dd60114Mathias AgopianClient::Client(const sp<SurfaceFlinger>& flinger)
2430b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    : mFlinger(flinger), mNameGenerator(1)
2431b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{
2432edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2433edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
243496f0819f81293076e652792794a961543e6750d7Mathias AgopianClient::~Client()
243596f0819f81293076e652792794a961543e6750d7Mathias Agopian{
243696f0819f81293076e652792794a961543e6750d7Mathias Agopian    const size_t count = mLayers.size();
243796f0819f81293076e652792794a961543e6750d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
243896f0819f81293076e652792794a961543e6750d7Mathias Agopian        sp<LayerBaseClient> layer(mLayers.valueAt(i).promote());
243996f0819f81293076e652792794a961543e6750d7Mathias Agopian        if (layer != 0) {
244096f0819f81293076e652792794a961543e6750d7Mathias Agopian            mFlinger->removeLayer(layer);
244196f0819f81293076e652792794a961543e6750d7Mathias Agopian        }
2442edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2443edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2444076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
244596f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t Client::initCheck() const {
2446b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return NO_ERROR;
2447edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2448076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
24494f113740180b6512b43723c4728f262882dc9b45Mathias Agopiansize_t Client::attachLayer(const sp<LayerBaseClient>& layer)
2450edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
24514f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    Mutex::Autolock _l(mLock);
24524f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    size_t name = mNameGenerator++;
245396f0819f81293076e652792794a961543e6750d7Mathias Agopian    mLayers.add(name, layer);
245496f0819f81293076e652792794a961543e6750d7Mathias Agopian    return name;
2455edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2456edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2457b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianvoid Client::detachLayer(const LayerBaseClient* layer)
245896f0819f81293076e652792794a961543e6750d7Mathias Agopian{
24594f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    Mutex::Autolock _l(mLock);
246096f0819f81293076e652792794a961543e6750d7Mathias Agopian    // we do a linear search here, because this doesn't happen often
246196f0819f81293076e652792794a961543e6750d7Mathias Agopian    const size_t count = mLayers.size();
246296f0819f81293076e652792794a961543e6750d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
246396f0819f81293076e652792794a961543e6750d7Mathias Agopian        if (mLayers.valueAt(i) == layer) {
246496f0819f81293076e652792794a961543e6750d7Mathias Agopian            mLayers.removeItemsAt(i, 1);
246596f0819f81293076e652792794a961543e6750d7Mathias Agopian            break;
246696f0819f81293076e652792794a961543e6750d7Mathias Agopian        }
246796f0819f81293076e652792794a961543e6750d7Mathias Agopian    }
246896f0819f81293076e652792794a961543e6750d7Mathias Agopian}
24694f113740180b6512b43723c4728f262882dc9b45Mathias Agopiansp<LayerBaseClient> Client::getLayerUser(int32_t i) const
24704f113740180b6512b43723c4728f262882dc9b45Mathias Agopian{
24714f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    Mutex::Autolock _l(mLock);
2472076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBaseClient> lbc;
24734f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    wp<LayerBaseClient> layer(mLayers.valueFor(i));
247496f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (layer != 0) {
247596f0819f81293076e652792794a961543e6750d7Mathias Agopian        lbc = layer.promote();
247696f0819f81293076e652792794a961543e6750d7Mathias Agopian        LOGE_IF(lbc==0, "getLayerUser(name=%d) is dead", int(i));
2477076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
2478076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return lbc;
2479edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2480edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2481a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
2482a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianstatus_t Client::onTransact(
2483a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
2484a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian{
2485a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // these must be checked
2486a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     IPCThreadState* ipc = IPCThreadState::self();
2487a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     const int pid = ipc->getCallingPid();
2488a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     const int uid = ipc->getCallingUid();
2489a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     const int self_pid = getpid();
2490a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     if (UNLIKELY(pid != self_pid && uid != AID_GRAPHICS && uid != 0)) {
2491a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian         // we're called from a different process, do the real check
249299b49840d309727678b77403d6cc9f920111623fMathias Agopian         if (!PermissionCache::checkCallingPermission(sAccessSurfaceFlinger))
2493a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian         {
2494a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian             LOGE("Permission Denial: "
2495a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                     "can't openGlobalTransaction pid=%d, uid=%d", pid, uid);
2496a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian             return PERMISSION_DENIED;
2497a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian         }
2498a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     }
2499a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     return BnSurfaceComposerClient::onTransact(code, data, reply, flags);
2500edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2501a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
2502a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
250396f0819f81293076e652792794a961543e6750d7Mathias Agopiansp<ISurface> Client::createSurface(
25040ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        ISurfaceComposerClient::surface_data_t* params,
2505b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        const String8& name,
2506b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
2507edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t flags)
2508edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2509b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    /*
2510a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     * createSurface must be called from the GL thread so that it can
2511a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     * have access to the GL context.
2512b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     */
2513b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
2514a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    class MessageCreateSurface : public MessageBase {
2515a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        sp<ISurface> result;
2516a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        SurfaceFlinger* flinger;
2517a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        ISurfaceComposerClient::surface_data_t* params;
2518a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        Client* client;
2519a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        const String8& name;
2520a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        DisplayID display;
2521a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        uint32_t w, h;
2522a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        PixelFormat format;
2523a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        uint32_t flags;
2524a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    public:
2525a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        MessageCreateSurface(SurfaceFlinger* flinger,
2526a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                ISurfaceComposerClient::surface_data_t* params,
2527a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                const String8& name, Client* client,
2528a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
2529a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                uint32_t flags)
2530a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            : flinger(flinger), params(params), client(client), name(name),
2531a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian              display(display), w(w), h(h), format(format), flags(flags)
2532a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        {
2533579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        }
2534a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        sp<ISurface> getResult() const { return result; }
2535a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        virtual bool handler() {
2536a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            result = flinger->createSurface(params, name, client,
2537a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                    display, w, h, format, flags);
2538a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            return true;
2539b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        }
2540a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    };
2541b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
2542a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    sp<MessageBase> msg = new MessageCreateSurface(mFlinger.get(),
2543a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            params, name, this, display, w, h, format, flags);
2544a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    mFlinger->postMessageSync(msg);
2545a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    return static_cast<MessageCreateSurface*>( msg.get() )->getResult();
2546b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
2547a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianstatus_t Client::destroySurface(SurfaceID sid) {
2548a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    return mFlinger->removeSurface(this, sid);
2549b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
2550b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
2551b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// ---------------------------------------------------------------------------
2552edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
25539a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::GraphicBufferAlloc() {}
25549a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
25559a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::~GraphicBufferAlloc() {}
25569a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
25579a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h,
2558d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        PixelFormat format, uint32_t usage, status_t* error) {
25599a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(w, h, format, usage));
25609a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    status_t err = graphicBuffer->initCheck();
2561d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian    *error = err;
2562a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (err != 0 || graphicBuffer->handle == 0) {
2563d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        if (err == NO_MEMORY) {
2564d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian            GraphicBuffer::dumpAllocationsToSystemLog();
2565d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        }
2566a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        LOGE("GraphicBufferAlloc::createGraphicBuffer(w=%d, h=%d) "
2567a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian             "failed (%s), handle=%p",
2568a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                w, h, strerror(-err), graphicBuffer->handle);
25699a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis        return 0;
25709a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    }
25719a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    return graphicBuffer;
25729a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis}
25739a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
25749a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis// ---------------------------------------------------------------------------
25759a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
2576edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane::GraphicPlane()
2577edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    : mHw(0)
2578edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2579edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2580edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2581edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane::~GraphicPlane() {
2582edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    delete mHw;
2583edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2584edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2585edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool GraphicPlane::initialized() const {
2586edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return mHw ? true : false;
2587edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2588edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
25892b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianint GraphicPlane::getWidth() const {
25902b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    return mWidth;
2591edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2592edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
25932b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianint GraphicPlane::getHeight() const {
25942b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    return mHeight;
25952b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian}
25962b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
25972b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianvoid GraphicPlane::setDisplayHardware(DisplayHardware *hw)
25982b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian{
25992b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mHw = hw;
26002b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
26012b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    // initialize the display orientation transform.
26022b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    // it's a constant that should come from the display driver.
26032b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    int displayOrientation = ISurfaceComposer::eOrientationDefault;
26042b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    char property[PROPERTY_VALUE_MAX];
26052b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    if (property_get("ro.sf.hwrotation", property, NULL) > 0) {
26062b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        //displayOrientation
26072b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        switch (atoi(property)) {
26082b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        case 90:
26092b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            displayOrientation = ISurfaceComposer::eOrientation90;
26102b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            break;
26112b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        case 270:
26122b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            displayOrientation = ISurfaceComposer::eOrientation270;
26132b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            break;
26142b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        }
26152b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    }
26162b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
26172b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float w = hw->getWidth();
26182b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float h = hw->getHeight();
26192b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    GraphicPlane::orientationToTransfrom(displayOrientation, w, h,
26202b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            &mDisplayTransform);
26212b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    if (displayOrientation & ISurfaceComposer::eOrientationSwapMask) {
26222b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayWidth = h;
26232b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayHeight = w;
26242b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    } else {
26252b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayWidth = w;
26262b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayHeight = h;
26272b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    }
26282b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
26292b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    setOrientation(ISurfaceComposer::eOrientationDefault);
2630edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2631edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2632edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t GraphicPlane::orientationToTransfrom(
2633edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int orientation, int w, int h, Transform* tr)
2634eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian{
2635eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    uint32_t flags = 0;
2636edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (orientation) {
2637edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientationDefault:
2638eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_0;
2639eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        break;
2640edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientation90:
2641eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_90;
2642edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
2643edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientation180:
2644eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_180;
2645edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
2646edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientation270:
2647eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_270;
2648edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
2649edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    default:
2650edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return BAD_VALUE;
2651edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2652eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    tr->set(flags, w, h);
2653edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
2654edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2655edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2656edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t GraphicPlane::setOrientation(int orientation)
2657edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2658edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // If the rotation can be handled in hardware, this is where
2659edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // the magic should happen.
26602b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
26612b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const DisplayHardware& hw(displayHardware());
26622b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float w = mDisplayWidth;
26632b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float h = mDisplayHeight;
26642b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mWidth = int(w);
26652b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mHeight = int(h);
26662b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
26672b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    Transform orientationTransform;
2668eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    GraphicPlane::orientationToTransfrom(orientation, w, h,
2669eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian            &orientationTransform);
2670eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    if (orientation & ISurfaceComposer::eOrientationSwapMask) {
2671eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        mWidth = int(h);
2672eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        mHeight = int(w);
2673edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2674eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian
26750d1318b974feba2e6ff13e36a1781343c2fce045Mathias Agopian    mOrientation = orientation;
26762b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mGlobalTransform = mDisplayTransform * orientationTransform;
2677edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
2678edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2679edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2680edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst DisplayHardware& GraphicPlane::displayHardware() const {
2681edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return *mHw;
2682edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2683edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
268459119e658a12279e8fff508f8773843de2d90917Mathias AgopianDisplayHardware& GraphicPlane::editDisplayHardware() {
268559119e658a12279e8fff508f8773843de2d90917Mathias Agopian    return *mHw;
268659119e658a12279e8fff508f8773843de2d90917Mathias Agopian}
268759119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2688edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst Transform& GraphicPlane::transform() const {
2689edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return mGlobalTransform;
2690edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2691edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2692076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias AgopianEGLDisplay GraphicPlane::getEGLDisplay() const {
2693076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return mHw->getEGLDisplay();
2694076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
2695076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
2696edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
2697edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2698edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
2699