SurfaceFlinger.cpp revision a44b04163957d6086362f6f365443c4c93379031
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"
53f171ab6da9cf9793093e50947aacdab8f2b0c9b2Mathias 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),
83cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        mResizeTransationPending(false),
84076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved(false),
85edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mBootTime(systemTime()),
86edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mVisibleRegionsDirty(false),
87a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        mHwWorkListDirty(false),
88edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mFreezeDisplay(false),
89abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        mElectronBeamAnimationMode(0),
90edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mFreezeCount(0),
91bcef13b666c7459241235bc6209837ae81884d2fThe Android Open Source Project        mFreezeDisplayTime(0),
92edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDebugRegion(0),
93edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDebugBackground(0),
948afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian        mDebugDDMS(0),
9573d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian        mDebugDisableHWC(0),
96a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian        mDebugDisableTransformHint(0),
979795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInSwapBuffers(0),
989795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastSwapBufferTime(0),
999795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInTransaction(0),
1009795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastTransactionTime(0),
1013330b203039dea366d4981db1408a460134b2d2cMathias Agopian        mBootFinished(false),
102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mConsoleSignals(0),
103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mSecureFrameBuffer(0)
104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    init();
106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::init()
109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    LOGI("SurfaceFlinger is starting");
111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // debugging stuff...
113edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char value[PROPERTY_VALUE_MAX];
1148afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    property_get("debug.sf.showupdates", value, "0");
116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDebugRegion = atoi(value);
1178afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    property_get("debug.sf.showbackground", value, "0");
119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDebugBackground = atoi(value);
120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1218afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    property_get("debug.sf.ddms", value, "0");
1228afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    mDebugDDMS = atoi(value);
1238afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    if (mDebugDDMS) {
1248afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian        DdmConnection::start(getServiceName());
1258afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    }
1268afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
12778fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian    LOGI_IF(mDebugRegion,       "showupdates enabled");
12878fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian    LOGI_IF(mDebugBackground,   "showbackground enabled");
1298afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    LOGI_IF(mDebugDDMS,         "DDMS debugging enabled");
130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::~SurfaceFlinger()
133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDeleteTextures(1, &mWormholeTexName);
135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1377303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopiansp<IMemoryHeap> SurfaceFlinger::getCblk() const
138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1397303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    return mServerHeap;
140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
141edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1427e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopiansp<ISurfaceComposerClient> SurfaceFlinger::createConnection()
143edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
14496f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<ISurfaceComposerClient> bclient;
14596f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<Client> client(new Client(this));
14696f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = client->initCheck();
14796f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR) {
14896f0819f81293076e652792794a961543e6750d7Mathias Agopian        bclient = client;
149edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
150edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return bclient;
151edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
152edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1539a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc()
1549a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis{
1559a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc());
1569a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    return gba;
1579a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis}
158b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst GraphicPlane& SurfaceFlinger::graphicPlane(int dpy) const
160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    LOGE_IF(uint32_t(dpy) >= DISPLAY_COUNT, "Invalid DisplayID %d", dpy);
162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(mGraphicPlanes[dpy]);
163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return plane;
164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane& SurfaceFlinger::graphicPlane(int dpy)
167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return const_cast<GraphicPlane&>(
169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const_cast<SurfaceFlinger const *>(this)->graphicPlane(dpy));
170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::bootFinished()
173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t now = systemTime();
175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t duration = now - mBootTime;
1768b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber    LOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
1773330b203039dea366d4981db1408a460134b2d2cMathias Agopian    mBootFinished = true;
1781f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
1791f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // wait patiently for the window manager death
1801f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    const String16 name("window");
1811f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    sp<IBinder> window(defaultServiceManager()->getService(name));
1821f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    if (window != 0) {
1831f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian        window->linkToDeath(this);
1841f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    }
1851f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
1861f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // stop boot animation
187a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    property_set("ctl.stop", "bootanim");
188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1901f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopianvoid SurfaceFlinger::binderDied(const wp<IBinder>& who)
1911f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian{
1921f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // the window manager died on us. prepare its eulogy.
1931f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
1941f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // unfreeze the screen in case it was... frozen
1951f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    mFreezeDisplayTime = 0;
1961f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    mFreezeCount = 0;
1971f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    mFreezeDisplay = false;
1981f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
1991f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // reset screen orientation
2001f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    setOrientation(0, eOrientationDefault, 0);
2011f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
2021f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // restart the boot-animation
2031f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    property_set("ctl.start", "bootanim");
2041f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian}
2051f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
206edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::onFirstRef()
207edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY);
209edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
210edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // Wait for the main thread to be done with its initialization
211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mReadyToRunBarrier.wait();
212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic inline uint16_t pack565(int r, int g, int b) {
215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return (r<<11)|(g<<5)|b;
216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
217edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::readyToRun()
219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    LOGI(   "SurfaceFlinger's main thread ready to run. "
221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            "Initializing graphics H/W...");
222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // we only support one display currently
224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int dpy = 0;
225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    {
227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // initialize the main display
228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GraphicPlane& plane(graphicPlane(dpy));
229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        DisplayHardware* const hw = new DisplayHardware(this, dpy);
230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        plane.setDisplayHardware(hw);
231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2337303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    // create the shared control-block
2347303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    mServerHeap = new MemoryHeapBase(4096,
2357303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian            MemoryHeapBase::READ_ONLY, "SurfaceFlinger read-only heap");
2367303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    LOGE_IF(mServerHeap==0, "can't create shared memory dealer");
2378b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
2387303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    mServerCblk = static_cast<surface_flinger_cblk_t*>(mServerHeap->getBase());
2397303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    LOGE_IF(mServerCblk==0, "can't get to shared control block's address");
2408b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
2417303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    new(mServerCblk) surface_flinger_cblk_t;
2427303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize primary screen
244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // (other display should be initialized in the same manner, but
245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // asynchronously, as they could come and go. None of this is supported
246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // yet).
247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(graphicPlane(dpy));
248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw = plane.displayHardware();
249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint32_t w = hw.getWidth();
250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint32_t h = hw.getHeight();
251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint32_t f = hw.getFormat();
252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    hw.makeCurrent();
253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize the shared control block
255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mServerCblk->connected |= 1<<dpy;
256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    display_cblk_t* dcblk = mServerCblk->displays + dpy;
257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    memset(dcblk, 0, sizeof(display_cblk_t));
2582b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    dcblk->w            = plane.getWidth();
2592b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    dcblk->h            = plane.getHeight();
260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->format       = f;
261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->orientation  = ISurfaceComposer::eOrientationDefault;
262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->xdpi         = hw.getDpiX();
263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->ydpi         = hw.getDpiY();
264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->fps          = hw.getRefreshRate();
265edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->density      = hw.getDensity();
266edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
267edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // Initialize OpenGL|ES
268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
2698b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber    glPixelStorei(GL_PACK_ALIGNMENT, 4);
270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glEnableClientState(GL_VERTEX_ARRAY);
271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glEnable(GL_SCISSOR_TEST);
272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glShadeModel(GL_FLAT);
273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_DITHER);
274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_CULL_FACE);
275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint16_t g0 = pack565(0x0F,0x1F,0x0F);
277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint16_t g1 = pack565(0x17,0x2f,0x17);
2789575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    const uint16_t wormholeTexData[4] = { g0, g1, g1, g0 };
279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glGenTextures(1, &mWormholeTexName);
280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glBindTexture(GL_TEXTURE_2D, mWormholeTexName);
281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
284edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
285edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0,
2869575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis            GL_RGB, GL_UNSIGNED_SHORT_5_6_5, wormholeTexData);
2879575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis
2889575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    const uint16_t protTexData[] = { pack565(0x03, 0x03, 0x03) };
2899575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glGenTextures(1, &mProtectedTexName);
2909575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glBindTexture(GL_TEXTURE_2D, mProtectedTexName);
2919575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2929575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2939575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
2949575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
2959575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0,
2969575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis            GL_RGB, GL_UNSIGNED_SHORT_5_6_5, protTexData);
297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glViewport(0, 0, w, h);
299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glMatrixMode(GL_PROJECTION);
300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glLoadIdentity();
301ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    // put the origin in the left-bottom corner
302ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    glOrthof(0, w, 0, h, 0, 1); // l=0, r=w ; b=0, t=h
303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mReadyToRunBarrier.open();
305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     *  We're now ready to accept clients...
308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
310a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    // start boot animation
311a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    property_set("ctl.start", "bootanim");
3128b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
313edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
314edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
315edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if 0
318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark -
319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark Events Handler
320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif
321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::waitForEvent()
323edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
324f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    while (true) {
325f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        nsecs_t timeout = -1;
3260408772e34931351d062f2088b611325ddaa6cdbMathias Agopian        const nsecs_t freezeDisplayTimeout = ms2ns(5000);
327f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        if (UNLIKELY(isFrozen())) {
328f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            // wait 5 seconds
329f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            const nsecs_t now = systemTime();
330f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            if (mFreezeDisplayTime == 0) {
331f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian                mFreezeDisplayTime = now;
332f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            }
333f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            nsecs_t waitTime = freezeDisplayTimeout - (now - mFreezeDisplayTime);
334f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            timeout = waitTime>0 ? waitTime : 0;
335bcef13b666c7459241235bc6209837ae81884d2fThe Android Open Source Project        }
336f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian
337bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        sp<MessageBase> msg = mEventQueue.waitMessage(timeout);
3380408772e34931351d062f2088b611325ddaa6cdbMathias Agopian
3390408772e34931351d062f2088b611325ddaa6cdbMathias Agopian        // see if we timed out
3400408772e34931351d062f2088b611325ddaa6cdbMathias Agopian        if (isFrozen()) {
3410408772e34931351d062f2088b611325ddaa6cdbMathias Agopian            const nsecs_t now = systemTime();
3420408772e34931351d062f2088b611325ddaa6cdbMathias Agopian            nsecs_t frozenTime = (now - mFreezeDisplayTime);
3430408772e34931351d062f2088b611325ddaa6cdbMathias Agopian            if (frozenTime >= freezeDisplayTimeout) {
344edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                // we timed out and are still frozen
345edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                LOGW("timeout expired mFreezeDisplay=%d, mFreezeCount=%d",
346edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        mFreezeDisplay, mFreezeCount);
3470408772e34931351d062f2088b611325ddaa6cdbMathias Agopian                mFreezeDisplayTime = 0;
348edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mFreezeCount = 0;
349bcef13b666c7459241235bc6209837ae81884d2fThe Android Open Source Project                mFreezeDisplay = false;
3500408772e34931351d062f2088b611325ddaa6cdbMathias Agopian            }
3510408772e34931351d062f2088b611325ddaa6cdbMathias Agopian        }
3520408772e34931351d062f2088b611325ddaa6cdbMathias Agopian
3530408772e34931351d062f2088b611325ddaa6cdbMathias Agopian        if (msg != 0) {
3540408772e34931351d062f2088b611325ddaa6cdbMathias Agopian            switch (msg->what) {
3550408772e34931351d062f2088b611325ddaa6cdbMathias Agopian                case MessageQueue::INVALIDATE:
3560408772e34931351d062f2088b611325ddaa6cdbMathias Agopian                    // invalidate message, just return to the main loop
3570408772e34931351d062f2088b611325ddaa6cdbMathias Agopian                    return;
358edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
359edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
360edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
361edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
362edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
363edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::signalEvent() {
364f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    mEventQueue.invalidate();
365edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
366edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
367582270d69db94286a248bd829f1ae6f910d45124Jamie Gennisbool SurfaceFlinger::authenticateSurfaceTexture(
368582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis        const sp<ISurfaceTexture>& surfaceTexture) const {
369134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    Mutex::Autolock _l(mStateLock);
370582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis    sp<IBinder> surfaceTextureBinder(surfaceTexture->asBinder());
371134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
372134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // Check the visible layer list for the ISurface
373134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
374134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    size_t count = currentLayers.size();
375134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    for (size_t i=0 ; i<count ; i++) {
376134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        const sp<LayerBase>& layer(currentLayers[i]);
377134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        sp<LayerBaseClient> lbc(layer->getLayerBaseClient());
378582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis        if (lbc != NULL) {
379582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder();
380582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            if (lbcBinder == surfaceTextureBinder) {
381582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis                return true;
382582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            }
383134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        }
384134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    }
385134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
386134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // Check the layers in the purgatory.  This check is here so that if a
387582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis    // SurfaceTexture gets destroyed before all the clients are done using it,
388582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis    // the error will not be reported as "surface XYZ is not authenticated", but
389134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // will instead fail later on when the client tries to use the surface,
390134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // which should be reported as "surface XYZ returned an -ENODEV".  The
391134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // purgatorized layers are no less authentic than the visible ones, so this
392134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // should not cause any harm.
393134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    size_t purgatorySize =  mLayerPurgatory.size();
394134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    for (size_t i=0 ; i<purgatorySize ; i++) {
395134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
396134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        sp<LayerBaseClient> lbc(layer->getLayerBaseClient());
397582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis        if (lbc != NULL) {
398582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder();
399582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            if (lbcBinder == surfaceTextureBinder) {
400582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis                return true;
401582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            }
402134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        }
403134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    }
404134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
405134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    return false;
406134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis}
407134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
408bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg,
409bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        nsecs_t reltime, uint32_t flags)
410edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
411bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    return mEventQueue.postMessage(msg, reltime, flags);
412bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian}
413bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
414bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,
415bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        nsecs_t reltime, uint32_t flags)
416bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian{
417bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    status_t res = mEventQueue.postMessage(msg, reltime, flags);
418bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    if (res == NO_ERROR) {
419bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        msg->wait();
420bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    }
421bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    return res;
422edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
423edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
424edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
425edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if 0
426edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark -
427edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark Main loop
428edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif
429edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
430edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool SurfaceFlinger::threadLoop()
431edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
432edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    waitForEvent();
433edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
434edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // check for transactions
435edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(mConsoleSignals)) {
436edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        handleConsoleEvents();
437edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
438edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
439698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    // if we're in a global transaction, don't do anything.
440698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
441698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    uint32_t transactionFlags = peekTransactionFlags(mask);
442698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    if (UNLIKELY(transactionFlags)) {
443698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        handleTransaction(transactionFlags);
444edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
445edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
446edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // post surfaces (if needed)
447edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    handlePageFlip();
448edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
449a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    if (UNLIKELY(mHwWorkListDirty)) {
450a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        // build the h/w work list
451a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        handleWorkList();
452a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
453a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
454edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw(graphicPlane(0).displayHardware());
455a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    if (LIKELY(hw.canDraw())) {
456edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // repaint the framebuffer (if needed)
45735b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian
45835b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        const int index = hw.getCurrentBufferIndex();
45935b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        GraphicLog& logger(GraphicLog::getInstance());
46035b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian
46135b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        logger.log(GraphicLog::SF_REPAINT, index);
462edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        handleRepaint();
463edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
46474faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian        // inform the h/w that we're done compositing
46535b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        logger.log(GraphicLog::SF_COMPOSITION_COMPLETE, index);
46674faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian        hw.compositionComplete();
46774faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian
46835b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        logger.log(GraphicLog::SF_SWAP_BUFFERS, index);
4698392b504bdf63ac7820c79c7217a89f2b2411bd0Antti Hatala        postFramebuffer();
4708392b504bdf63ac7820c79c7217a89f2b2411bd0Antti Hatala
47135b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        logger.log(GraphicLog::SF_REPAINT_DONE, index);
472edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
473edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // pretend we did the post
474e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian        hw.compositionComplete();
475edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        usleep(16667); // 60 fps period
476edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
477edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return true;
478edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
479edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
480edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer()
481edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
482a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
483a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    const nsecs_t now = systemTime();
484a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = now;
485a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    hw.flip(mSwapRegion);
486a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mLastSwapBufferTime = systemTime() - now;
487a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = 0;
488a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mSwapRegion.clear();
489edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
490edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
491edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleConsoleEvents()
492edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
493edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // something to do with the console
494edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw = graphicPlane(0).displayHardware();
495edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
496edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int what = android_atomic_and(0, &mConsoleSignals);
497edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (what & eConsoleAcquired) {
498edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        hw.acquireScreen();
4999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // this is a temporary work-around, eventually this should be called
5009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // by the power-manager
501abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        SurfaceFlinger::turnElectronBeamOn(mElectronBeamAnimationMode);
502edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
503edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
504edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (what & eConsoleReleased) {
50559119e658a12279e8fff508f8773843de2d90917Mathias Agopian        if (hw.isScreenAcquired()) {
506edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            hw.releaseScreen();
507edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
508edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
509edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
510edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDirtyRegion.set(hw.bounds());
511edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
512edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
513edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
514edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
515ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    Mutex::Autolock _l(mStateLock);
516ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    const nsecs_t now = systemTime();
517ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = now;
518ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
519ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // Here we're guaranteed that some transaction flags are set
520ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // so we can call handleTransactionLocked() unconditionally.
521ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // We call getTransactionFlags(), which will also clear the flags,
522ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // with mStateLock held to guarantee that mCurrentState won't change
523ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // until the transaction is committed.
524ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
525ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
526ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    transactionFlags = getTransactionFlags(mask);
527ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    handleTransactionLocked(transactionFlags);
528ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
529ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mLastTransactionTime = systemTime() - now;
530ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = 0;
531ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    invalidateHwcGeometry();
532ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // here the transaction has been committed
5333d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian}
534edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
535ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopianvoid SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
5363d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{
5373d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    const LayerVector& currentLayers(mCurrentState.layersSortedByZ);
538edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t count = currentLayers.size();
539edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
540edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
541edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Traversal of the children
542edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * (perform the transaction for each of them if needed)
543edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
544edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
545edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const bool layersNeedTransaction = transactionFlags & eTraversalNeeded;
546edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (layersNeedTransaction) {
547edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (size_t i=0 ; i<count ; i++) {
548076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            const sp<LayerBase>& layer = currentLayers[i];
549edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
550edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (!trFlags) continue;
551edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
552edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const uint32_t flags = layer->doTransaction(0);
553edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (flags & Layer::eVisibleRegion)
554edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mVisibleRegionsDirty = true;
555edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
556edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
557edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
558edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
559edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Perform our own transaction if needed
560edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
561edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (transactionFlags & eTransactionNeeded) {
563edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (mCurrentState.orientation != mDrawingState.orientation) {
564edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // the orientation has changed, recompute all visible regions
565edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // and invalidate everything.
566edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
567edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int dpy = 0;
568edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int orientation = mCurrentState.orientation;
56921230c6410bdab13cd2bd274da54b1e4061b6035Jeff Brown            // Currently unused: const uint32_t flags = mCurrentState.orientationFlags;
570edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            GraphicPlane& plane(graphicPlane(dpy));
571edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            plane.setOrientation(orientation);
572edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
573edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // update the shared control block
574edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const DisplayHardware& hw(plane.displayHardware());
575edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            volatile display_cblk_t* dcblk = mServerCblk->displays + dpy;
576edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dcblk->orientation = orientation;
5772b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            dcblk->w = plane.getWidth();
5782b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            dcblk->h = plane.getHeight();
579edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
580edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
581edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mDirtyRegion.set(hw.bounds());
582edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
583edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
584edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (mCurrentState.freezeDisplay != mDrawingState.freezeDisplay) {
585edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // freezing or unfreezing the display -> trigger animation if needed
586edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mFreezeDisplay = mCurrentState.freezeDisplay;
587064e1e672e62094b32f8cf7a77a3b04c3309dc79Mathias Agopian            if (mFreezeDisplay)
588064e1e672e62094b32f8cf7a77a3b04c3309dc79Mathias Agopian                 mFreezeDisplayTime = 0;
589edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
590edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5910aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        if (currentLayers.size() > mDrawingState.layersSortedByZ.size()) {
5920aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            // layers have been added
593edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
594edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
595edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5960aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        // some layers might have been removed, so
5970aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        // we need to update the regions they're exposing.
5980aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        if (mLayersRemoved) {
59948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian            mLayersRemoved = false;
600edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
6010aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            const LayerVector& previousLayers(mDrawingState.layersSortedByZ);
6023d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian            const size_t count = previousLayers.size();
6033d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian            for (size_t i=0 ; i<count ; i++) {
6040aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                const sp<LayerBase>& layer(previousLayers[i]);
6050aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                if (currentLayers.indexOf( layer ) < 0) {
6060aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                    // this layer is not visible anymore
6075d7126b625c8c4a7b945e8c247b63abff7bc13b6Mathias Agopian                    mDirtyRegionRemovedLayer.orSelf(layer->visibleRegionScreen);
6080aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                }
6090aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            }
610edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
611edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
612edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
613edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    commitTransaction();
614edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
615edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
616edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectsp<FreezeLock> SurfaceFlinger::getFreezeLock() const
617edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
618edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return new FreezeLock(const_cast<SurfaceFlinger *>(this));
619edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
620edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
621edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::computeVisibleRegions(
6221bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian    const LayerVector& currentLayers, Region& dirtyRegion, Region& opaqueRegion)
623edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
624edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(graphicPlane(0));
625edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Transform& planeTransform(plane.transform());
626ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian    const DisplayHardware& hw(plane.displayHardware());
627ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian    const Region screenRegion(hw.bounds());
628edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
629edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveOpaqueLayers;
630edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveCoveredLayers;
631edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region dirty;
632edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
633edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    bool secureFrameBuffer = false;
634edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
635edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t i = currentLayers.size();
636edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    while (i--) {
637076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        const sp<LayerBase>& layer = currentLayers[i];
638edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->validateVisibility(planeTransform);
639edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
640edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // start with the whole surface at its current location
641970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian        const Layer::State& s(layer->drawingState());
642edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
643ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
644ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * opaqueRegion: area of a surface that is fully opaque.
645ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
646edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region opaqueRegion;
647ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
648ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
649ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visibleRegion: area of a surface that is visible on screen
650ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * and not fully transparent. This is essentially the layer's
651ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * footprint minus the opaque regions above it.
652ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * Areas covered by a translucent surface are considered visible.
653ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
654edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region visibleRegion;
655ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
656ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
657ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * coveredRegion: area of a surface that is covered by all
658ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visible regions above it (which includes the translucent areas).
659ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
660edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region coveredRegion;
661ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
662ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
663ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // handle hidden surfaces by setting the visible region to empty
664970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian        if (LIKELY(!(s.flags & ISurfaceComposer::eLayerHidden) && s.alpha)) {
665a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            const bool translucent = !layer->isOpaque();
666970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian            const Rect bounds(layer->visibleBounds());
667edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            visibleRegion.set(bounds);
668ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            visibleRegion.andSelf(screenRegion);
669ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            if (!visibleRegion.isEmpty()) {
670ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // Remove the transparent area from the visible region
671ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (translucent) {
672ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    visibleRegion.subtractSelf(layer->transparentRegionScreen);
673ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
674edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
675ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // compute the opaque region
676ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                const int32_t layerOrientation = layer->getOrientation();
677ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (s.alpha==255 && !translucent &&
678ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                        ((layerOrientation & Transform::ROT_INVALID) == false)) {
679ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    // the opaque region is the layer's footprint
680ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    opaqueRegion = visibleRegion;
681ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
682edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
683edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
684edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
685ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Clip the covered region to the visible region
686ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        coveredRegion = aboveCoveredLayers.intersect(visibleRegion);
687ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
688ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveCoveredLayers for next (lower) layer
689ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        aboveCoveredLayers.orSelf(visibleRegion);
690ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
691edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // subtract the opaque region covered by the layers above us
692edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        visibleRegion.subtractSelf(aboveOpaqueLayers);
693edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
694edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // compute this layer's dirty region
695edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (layer->contentDirty) {
696edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // we need to invalidate the whole region
697edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dirty = visibleRegion;
698edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // as well, as the old visible region
699edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dirty.orSelf(layer->visibleRegionScreen);
700edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->contentDirty = false;
701edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
702a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian            /* compute the exposed region:
703ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   the exposed region consists of two components:
704ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   1) what's VISIBLE now and was COVERED before
705ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   2) what's EXPOSED now less what was EXPOSED before
706ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
707ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * note that (1) is conservative, we start with the whole
708ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * visible region but only keep what used to be covered by
709ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * something -- which mean it may have been exposed.
710ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
711ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * (2) handles areas that were not covered by anything but got
712ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * exposed because of a resize.
713a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian             */
714ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region newExposed = visibleRegion - coveredRegion;
715ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldVisibleRegion = layer->visibleRegionScreen;
716ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldCoveredRegion = layer->coveredRegionScreen;
717ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldExposed = oldVisibleRegion - oldCoveredRegion;
718ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed);
719edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
720edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirty.subtractSelf(aboveOpaqueLayers);
721edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
722edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // accumulate to the screen dirty region
723edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirtyRegion.orSelf(dirty);
724edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
725ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveOpaqueLayers for next (lower) layer
726edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        aboveOpaqueLayers.orSelf(opaqueRegion);
7278b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
728edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // Store the visible region is screen space
729edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setVisibleRegion(visibleRegion);
730edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setCoveredRegion(coveredRegion);
731edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
732970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian        // If a secure layer is partially visible, lock-down the screen!
733edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (layer->isSecure() && !visibleRegion.isEmpty()) {
734edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            secureFrameBuffer = true;
735edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
736edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
737edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
738970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian    // invalidate the areas where a layer was removed
739970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian    dirtyRegion.orSelf(mDirtyRegionRemovedLayer);
740970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian    mDirtyRegionRemovedLayer.clear();
741970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian
742edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mSecureFrameBuffer = secureFrameBuffer;
743edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    opaqueRegion = aboveOpaqueLayers;
744edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
745edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
746edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
747edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::commitTransaction()
748edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
749edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDrawingState = mCurrentState;
750cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mResizeTransationPending = false;
751cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mTransactionCV.broadcast();
752edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
753edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
754edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handlePageFlip()
755edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
756edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    bool visibleRegions = mVisibleRegionsDirty;
7571bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian    const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
758edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    visibleRegions |= lockPageFlip(currentLayers);
759edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
760edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const DisplayHardware& hw = graphicPlane(0).displayHardware();
761edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const Region screenRegion(hw.bounds());
762edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (visibleRegions) {
763edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            Region opaqueRegion;
764edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            computeVisibleRegions(currentLayers, mDirtyRegion, opaqueRegion);
7654da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
7664da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            /*
7674da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian             *  rebuild the visible layer list
7684da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian             */
7691bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian            const size_t count = currentLayers.size();
7704da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            mVisibleLayersSortedByZ.clear();
7714da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            mVisibleLayersSortedByZ.setCapacity(count);
7724da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            for (size_t i=0 ; i<count ; i++) {
7734da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian                if (!currentLayers[i]->visibleRegionScreen.isEmpty())
7744da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian                    mVisibleLayersSortedByZ.add(currentLayers[i]);
7754da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            }
7764da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
777edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mWormholeRegion = screenRegion.subtract(opaqueRegion);
778edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = false;
779ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian            invalidateHwcGeometry();
780edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
781edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
782edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    unlockPageFlip(currentLayers);
783edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDirtyRegion.andSelf(screenRegion);
784edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
785edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
786ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopianvoid SurfaceFlinger::invalidateHwcGeometry()
787ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian{
788ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian    mHwWorkListDirty = true;
789ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian}
790ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian
791edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool SurfaceFlinger::lockPageFlip(const LayerVector& currentLayers)
792edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
793edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    bool recomputeVisibleRegions = false;
794edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t count = currentLayers.size();
795076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBase> const* layers = currentLayers.array();
796edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (size_t i=0 ; i<count ; i++) {
797b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
798edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->lockPageFlip(recomputeVisibleRegions);
799edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
800edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return recomputeVisibleRegions;
801edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
802edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
803edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::unlockPageFlip(const LayerVector& currentLayers)
804edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
805edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(graphicPlane(0));
806edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Transform& planeTransform(plane.transform());
807edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t count = currentLayers.size();
808076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBase> const* layers = currentLayers.array();
809edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (size_t i=0 ; i<count ; i++) {
810b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
811edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->unlockPageFlip(planeTransform, mDirtyRegion);
812edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
813edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
814edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
815a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopianvoid SurfaceFlinger::handleWorkList()
816a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian{
817a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    mHwWorkListDirty = false;
818a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    HWComposer& hwc(graphicPlane(0).displayHardware().getHwComposer());
819a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    if (hwc.initCheck() == NO_ERROR) {
820a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        const Vector< sp<LayerBase> >& currentLayers(mVisibleLayersSortedByZ);
821a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        const size_t count = currentLayers.size();
822a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        hwc.createWorkList(count);
82345721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        hwc_layer_t* const cur(hwc.getLayers());
82445721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        for (size_t i=0 ; cur && i<count ; i++) {
82545721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            currentLayers[i]->setGeometry(&cur[i]);
82653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian            if (mDebugDisableHWC || mDebugRegion) {
82773d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian                cur[i].compositionType = HWC_FRAMEBUFFER;
82873d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian                cur[i].flags |= HWC_SKIP_LAYER;
82973d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian            }
830a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        }
831a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
832a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian}
833b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian
834edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleRepaint()
835edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
836b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // compute the invalid region
8370656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian    mSwapRegion.orSelf(mDirtyRegion);
838edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
839edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(mDebugRegion)) {
840edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        debugFlashRegions();
841edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
842edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
843b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // set the frame buffer
844b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
845b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    glMatrixMode(GL_MODELVIEW);
846b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    glLoadIdentity();
847edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
848edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t flags = hw.getFlags();
8498b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber    if ((flags & DisplayHardware::SWAP_RECTANGLE) ||
8508b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber        (flags & DisplayHardware::BUFFER_PRESERVED))
851df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian    {
85229d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // we can redraw only what's dirty, but since SWAP_RECTANGLE only
85329d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // takes a rectangle, we must make sure to update that whole
85429d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // rectangle in that case
85529d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        if (flags & DisplayHardware::SWAP_RECTANGLE) {
856b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            // TODO: we really should be able to pass a region to
85729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // SWAP_RECTANGLE so that we don't have to redraw all this.
8580656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian            mDirtyRegion.set(mSwapRegion.bounds());
85929d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        } else {
86029d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // in the BUFFER_PRESERVED case, obviously, we can update only
86129d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // what's needed and nothing more.
86229d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // NOTE: this is NOT a common case, as preserving the backbuffer
86329d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // is costly and usually involves copying the whole update back.
86429d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        }
865edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
86695a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian        if (flags & DisplayHardware::PARTIAL_UPDATES) {
86729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // We need to redraw the rectangle that will be updated
868df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian            // (pushed to the framebuffer).
86995a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian            // This is needed because PARTIAL_UPDATES only takes one
87029d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // rectangle instead of a region (see DisplayHardware::flip())
8710656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian            mDirtyRegion.set(mSwapRegion.bounds());
872edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
87329d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // we need to redraw everything (the whole screen)
874edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mDirtyRegion.set(hw.bounds());
8750656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian            mSwapRegion = mDirtyRegion;
876edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
877edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
878edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
8799c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    setupHardwareComposer(mDirtyRegion);
880edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    composeSurfaces(mDirtyRegion);
881edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
8829c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    // update the swap region and clear the dirty region
8839c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    mSwapRegion.orSelf(mDirtyRegion);
884edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDirtyRegion.clear();
885edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
886edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
8879c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopianvoid SurfaceFlinger::setupHardwareComposer(Region& dirtyInOut)
888edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
889f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
890f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    HWComposer& hwc(hw.getHwComposer());
891f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    hwc_layer_t* const cur(hwc.getLayers());
892f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    if (!cur) {
8939c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        return;
894edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
895a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
8964da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian    const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
89745721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    size_t count = layers.size();
898a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
899f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    LOGE_IF(hwc.getNumLayers() != count,
90045721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            "HAL number of layers (%d) doesn't match surfaceflinger (%d)",
90145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            hwc.getNumLayers(), count);
902a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
90345721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    // just to be extra-safe, use the smallest count
90424925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling    if (hwc.initCheck() == NO_ERROR) {
90524925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling        count = count < hwc.getNumLayers() ? count : hwc.getNumLayers();
90624925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling    }
907a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
90845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    /*
90945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     *  update the per-frame h/w composer data for each layer
91045721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     *  and build the transparent region of the FB
91145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     */
912f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
913f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
914f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        layer->setPerFrameData(&cur[i]);
915f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    }
9169c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    const size_t fbLayerCount = hwc.getLayerCount(HWC_FRAMEBUFFER);
917f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    status_t err = hwc.prepare();
918f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    LOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
919f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian
920f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    if (err == NO_ERROR) {
9219c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // what's happening here is tricky.
9229c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // we want to clear all the layers with the CLEAR_FB flags
9239c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // that are opaque.
9249c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // however, since some GPU are efficient at preserving
9259c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // the backbuffer, we want to take advantage of that so we do the
9269c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // clear only in the dirty region (other areas will be preserved
9279c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // on those GPUs).
9289c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        //   NOTE: on non backbuffer preserving GPU, the dirty region
9299c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        //   has already been expanded as needed, so the code is correct
9309c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        //   there too.
9319c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        //
9329c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // However, the content of the framebuffer cannot be trusted when
9339c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // we switch to/from FB/OVERLAY, in which case we need to
9349c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // expand the dirty region to those areas too.
9359c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        //
9369c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // Note also that there is a special case when switching from
9379c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // "no layers in FB" to "some layers in FB", where we need to redraw
9389c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // the entire FB, since some areas might contain uninitialized
9399c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // data.
9409c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        //
9419c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // Also we want to make sure to not clear areas that belong to
9429c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // layers above that won't redraw (we would just erasing them),
9439c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // that is, we can't erase anything outside the dirty region.
944a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
9459c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        Region transparent;
946f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian
9479c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        if (!fbLayerCount && hwc.getLayerCount(HWC_FRAMEBUFFER)) {
9489c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian            transparent.set(hw.getBounds());
9499c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian            dirtyInOut = transparent;
9509c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        } else {
9519c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian            for (size_t i=0 ; i<count ; i++) {
9529c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                const sp<LayerBase>& layer(layers[i]);
9539c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                if ((cur[i].hints & HWC_HINT_CLEAR_FB) && layer->isOpaque()) {
9549c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                    transparent.orSelf(layer->visibleRegionScreen);
9559c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                }
9569c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                bool isOverlay = (cur[i].compositionType != HWC_FRAMEBUFFER);
9579c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                if (isOverlay != layer->isOverlay()) {
9589c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                    // we transitioned to/from overlay, so add this layer
9599c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                    // to the dirty region so the framebuffer can be either
9609c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                    // cleared or redrawn.
9619c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                    dirtyInOut.orSelf(layer->visibleRegionScreen);
9629c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                }
9639c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                layer->setOverlay(isOverlay);
964f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian            }
9659c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian            // don't erase stuff outside the dirty region
9669c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian            transparent.andSelf(dirtyInOut);
967f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        }
968f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian
969f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        /*
970f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian         *  clear the area of the FB that need to be transparent
971f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian         */
972f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        if (!transparent.isEmpty()) {
973f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian            glClearColor(0,0,0,0);
974f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian            Region::const_iterator it = transparent.begin();
975f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian            Region::const_iterator const end = transparent.end();
976f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian            const int32_t height = hw.getHeight();
977f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian            while (it != end) {
978f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian                const Rect& r(*it++);
979f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian                const GLint sy = height - (r.top + r.height());
980f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian                glScissor(r.left, sy, r.width(), r.height());
981f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian                glClear(GL_COLOR_BUFFER_BIT);
982f20a32415d055336bc6016fa2de36d126db32746Mathias Agopian            }
983a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        }
984a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
985f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian}
986f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian
987f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopianvoid SurfaceFlinger::composeSurfaces(const Region& dirty)
988f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian{
989cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
990cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian    HWComposer& hwc(hw.getHwComposer());
991cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian
992cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian    const size_t fbLayerCount = hwc.getLayerCount(HWC_FRAMEBUFFER);
993cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian    if (UNLIKELY(fbLayerCount && !mWormholeRegion.isEmpty())) {
994f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        // should never happen unless the window manager has a bug
995f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        // draw something...
996f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        drawWormhole();
997f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    }
99845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian
99945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    /*
100045721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     * and then, render the layers targeted at the framebuffer
100145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     */
1002cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian    hwc_layer_t* const cur(hwc.getLayers());
1003f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
1004f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    size_t count = layers.size();
100545721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
10069c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        if (cur && (cur[i].compositionType != HWC_FRAMEBUFFER)) {
1007f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian            continue;
100845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        }
100945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
101045721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        const Region clip(dirty.intersect(layer->visibleRegionScreen));
101145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        if (!clip.isEmpty()) {
101245721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            layer->draw(clip);
101345721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        }
101445721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    }
1015edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1016edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1017edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::debugFlashRegions()
1018edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
10190a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
10200a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    const uint32_t flags = hw.getFlags();
102153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian    const int32_t height = hw.getHeight();
10220656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian    if (mSwapRegion.isEmpty()) {
102353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian        return;
102453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian    }
10250a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
10260a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    if (!((flags & DisplayHardware::SWAP_RECTANGLE) ||
10270a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian            (flags & DisplayHardware::BUFFER_PRESERVED))) {
10280a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        const Region repaint((flags & DisplayHardware::PARTIAL_UPDATES) ?
10290a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian                mDirtyRegion.bounds() : hw.bounds());
10300a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        composeSurfaces(repaint);
10310a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    }
10320a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
1033edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_BLEND);
1034edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_DITHER);
1035edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_SCISSOR_TEST);
1036edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
10370926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    static int toggle = 0;
10380926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    toggle = 1 - toggle;
10390926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    if (toggle) {
10400a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        glColor4f(1, 0, 1, 1);
10410926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    } else {
10420a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        glColor4f(1, 1, 0, 1);
10430926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    }
1044edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
104520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    Region::const_iterator it = mDirtyRegion.begin();
104620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    Region::const_iterator const end = mDirtyRegion.end();
104720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    while (it != end) {
104820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        const Rect& r = *it++;
1049edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLfloat vertices[][2] = {
105053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.left,  height - r.top },
105153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.left,  height - r.bottom },
105253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.right, height - r.bottom },
105353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.right, height - r.top }
1054edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        };
1055edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glVertexPointer(2, GL_FLOAT, 0, vertices);
1056edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1057edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
10580a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
10590656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian    hw.flip(mSwapRegion);
1060edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1061edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mDebugRegion > 1)
10620a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        usleep(mDebugRegion * 1000);
1063edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1064edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glEnable(GL_SCISSOR_TEST);
1065edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1066edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1067edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::drawWormhole() const
1068edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1069edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Region region(mWormholeRegion.intersect(mDirtyRegion));
1070edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (region.isEmpty())
1071edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1072edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1073edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw(graphicPlane(0).displayHardware());
1074edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int32_t width = hw.getWidth();
1075edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int32_t height = hw.getHeight();
1076edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1077edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_BLEND);
1078edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_DITHER);
1079edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1080edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (LIKELY(!mDebugBackground)) {
10810a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        glClearColor(0,0,0,0);
108220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        Region::const_iterator it = region.begin();
108320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        Region::const_iterator const end = region.end();
108420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        while (it != end) {
108520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            const Rect& r = *it++;
1086edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const GLint sy = height - (r.top + r.height());
1087edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glScissor(r.left, sy, r.width(), r.height());
1088edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glClear(GL_COLOR_BUFFER_BIT);
1089edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1090edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
1091edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GLshort vertices[][2] = { { 0, 0 }, { width, 0 },
1092edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                { width, height }, { 0, height }  };
1093edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GLshort tcoords[][2] = { { 0, 0 }, { 1, 0 },  { 1, 1 }, { 0, 1 } };
1094edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glVertexPointer(2, GL_SHORT, 0, vertices);
1095edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glTexCoordPointer(2, GL_SHORT, 0, tcoords);
1096edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
10977f198b6bff54af3c8e8ac32b83ffc6488e773ac1Michael I. Gold#if defined(GL_OES_EGL_image_external)
10981f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian        if (GLExtensions::getInstance().haveTextureExternal()) {
10991f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian            glDisable(GL_TEXTURE_EXTERNAL_OES);
11001f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian        }
11010a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian#endif
1102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glEnable(GL_TEXTURE_2D);
1103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glBindTexture(GL_TEXTURE_2D, mWormholeTexName);
1104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glMatrixMode(GL_TEXTURE);
1106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glLoadIdentity();
1107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glScalef(width*(1.0f/32.0f), height*(1.0f/32.0f), 1);
110820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        Region::const_iterator it = region.begin();
110920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        Region::const_iterator const end = region.end();
111020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        while (it != end) {
111120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            const Rect& r = *it++;
1112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const GLint sy = height - (r.top + r.height());
1113edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glScissor(r.left, sy, r.width(), r.height());
1114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1117a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        glDisable(GL_TEXTURE_2D);
1118ebeb7095961e09f5cff0c7cf2c04fa4770b2e033Mathias Agopian        glLoadIdentity();
1119ebeb7095961e09f5cff0c7cf2c04fa4770b2e033Mathias Agopian        glMatrixMode(GL_MODELVIEW);
1120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::debugShowFPS() const
1124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1125edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    static int mFrameCount;
1126edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    static int mLastFrameCount = 0;
1127edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    static nsecs_t mLastFpsTime = 0;
1128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    static float mFps = 0;
1129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mFrameCount++;
1130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    nsecs_t now = systemTime();
1131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    nsecs_t diff = now - mLastFpsTime;
1132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (diff > ms2ns(250)) {
1133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mFps =  ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff;
1134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mLastFpsTime = now;
1135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mLastFrameCount = mFrameCount;
1136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // XXX: mFPS has the value we want
1138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project }
1139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1140076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::addLayer(const sp<LayerBase>& layer)
1141edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1142edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
1143edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    addLayer_l(layer);
1144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
1145edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1146edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1147edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1148076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::addLayer_l(const sp<LayerBase>& layer)
1149edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1150f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian    ssize_t i = mCurrentState.layersSortedByZ.add(layer);
11511b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    return (i < 0) ? status_t(i) : status_t(NO_ERROR);
11521b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian}
11531b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
115496f0819f81293076e652792794a961543e6750d7Mathias Agopianssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
115596f0819f81293076e652792794a961543e6750d7Mathias Agopian        const sp<LayerBaseClient>& lbc)
11561b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
115796f0819f81293076e652792794a961543e6750d7Mathias Agopian    // attach this layer to the client
11584f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    size_t name = client->attachLayer(lbc);
11594f113740180b6512b43723c4728f262882dc9b45Mathias Agopian
11604f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    Mutex::Autolock _l(mStateLock);
116196f0819f81293076e652792794a961543e6750d7Mathias Agopian
116296f0819f81293076e652792794a961543e6750d7Mathias Agopian    // add this layer to the current state list
116396f0819f81293076e652792794a961543e6750d7Mathias Agopian    addLayer_l(lbc);
116496f0819f81293076e652792794a961543e6750d7Mathias Agopian
11654f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    return ssize_t(name);
116696f0819f81293076e652792794a961543e6750d7Mathias Agopian}
116796f0819f81293076e652792794a961543e6750d7Mathias Agopian
116896f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer)
116996f0819f81293076e652792794a961543e6750d7Mathias Agopian{
117096f0819f81293076e652792794a961543e6750d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
117196f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = purgatorizeLayer_l(layer);
117296f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR)
117396f0819f81293076e652792794a961543e6750d7Mathias Agopian        setTransactionFlags(eTransactionNeeded);
117496f0819f81293076e652792794a961543e6750d7Mathias Agopian    return err;
1175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1177076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase)
1178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1179b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<LayerBaseClient> lbc(layerBase->getLayerBaseClient());
1180b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (lbc != 0) {
11810d1561275e80073807ac04728951782d943f8882Mathias Agopian        mLayerMap.removeItem( lbc->getSurfaceBinder() );
1182b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    }
1183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase);
1184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (index >= 0) {
1185076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved = true;
1186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
1187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
11883d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    return status_t(index);
1189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
11919a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase)
11929a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
119376cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    // First add the layer to the purgatory list, which makes sure it won't
119476cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    // go away, then remove it from the main list (through a transaction).
11959a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    ssize_t err = removeLayer_l(layerBase);
119676cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    if (err >= 0) {
119776cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian        mLayerPurgatory.add(layerBase);
119876cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    }
11998c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian
12000b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian    layerBase->onRemoved();
12010b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian
12023d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // it's possible that we don't find a layer, because it might
12033d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // have been destroyed already -- this is not technically an error
120496f0819f81293076e652792794a961543e6750d7Mathias Agopian    // from the user because there is a race between Client::destroySurface(),
120596f0819f81293076e652792794a961543e6750d7Mathias Agopian    // ~Client() and ~ISurface().
12069a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err;
12079a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
12089a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
120996f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::invalidateLayerVisibility(const sp<LayerBase>& layer)
1210edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
121196f0819f81293076e652792794a961543e6750d7Mathias Agopian    layer->forceVisibilityTransaction();
121296f0819f81293076e652792794a961543e6750d7Mathias Agopian    setTransactionFlags(eTraversalNeeded);
121396f0819f81293076e652792794a961543e6750d7Mathias Agopian    return NO_ERROR;
1214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1216dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopianuint32_t SurfaceFlinger::peekTransactionFlags(uint32_t flags)
1217dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian{
1218dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian    return android_atomic_release_load(&mTransactionFlags);
1219dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian}
1220dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian
1221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags)
1222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return android_atomic_and(~flags, &mTransactionFlags) & flags;
1224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1226bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags)
1227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t old = android_atomic_or(flags, &mTransactionFlags);
1229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((old & flags)==0) { // wake the server up
1230bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        signalEvent();
1231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return old;
1233edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1236b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennisvoid SurfaceFlinger::setTransactionState(const Vector<ComposerState>& state,
1237b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis        int orientation) {
1238698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
1239cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
1240698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    uint32_t flags = 0;
1241b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis    if (mCurrentState.orientation != orientation) {
1242b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis        if (uint32_t(orientation)<=eOrientation270 || orientation==42) {
1243b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis            mCurrentState.orientation = orientation;
1244b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis            flags |= eTransactionNeeded;
1245b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis            mResizeTransationPending = true;
1246b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis        } else if (orientation != eOrientationUnchanged) {
1247b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis            LOGW("setTransactionState: ignoring unrecognized orientation: %d",
1248b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis                    orientation);
1249b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis        }
1250b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis    }
1251b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis
1252698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    const size_t count = state.size();
1253698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
1254698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const ComposerState& s(state[i]);
1255698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        sp<Client> client( static_cast<Client *>(s.client.get()) );
1256698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        flags |= setClientStateLocked(client, s.state);
1257698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    }
1258698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    if (flags) {
1259698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        setTransactionFlags(flags);
1260698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    }
1261698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian
1262698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    signalEvent();
1263698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian
1264698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    // if there is a transaction with a resize, wait for it to
1265698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    // take effect before returning.
1266698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    while (mResizeTransationPending) {
1267698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
1268698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (CC_UNLIKELY(err != NO_ERROR)) {
1269698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            // just in case something goes wrong in SF, return to the
1270698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            // called after a few seconds.
1271698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            LOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!");
1272698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            mResizeTransationPending = false;
1273698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            break;
1274cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        }
1275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1278edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::freezeDisplay(DisplayID dpy, uint32_t flags)
1279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
1281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return BAD_VALUE;
1282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
1284edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mCurrentState.freezeDisplay = 1;
1285edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    setTransactionFlags(eTransactionNeeded);
1286edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1287edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // flags is intended to communicate some sort of animation behavior
128862b74444be6742ab6b877918c85caeb9f2f1a2c9Mathias Agopian    // (for instance fading)
1289edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1290edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1291edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1292edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::unfreezeDisplay(DisplayID dpy, uint32_t flags)
1293edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1294edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
1295edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return BAD_VALUE;
1296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
1298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mCurrentState.freezeDisplay = 0;
1299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    setTransactionFlags(eTransactionNeeded);
1300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1301edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // flags is intended to communicate some sort of animation behavior
130262b74444be6742ab6b877918c85caeb9f2f1a2c9Mathias Agopian    // (for instance fading)
1303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
13068b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huberint SurfaceFlinger::setOrientation(DisplayID dpy,
1307c08731e756868653d09d3e49b723706df3687070Mathias Agopian        int orientation, uint32_t flags)
1308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
1310edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return BAD_VALUE;
1311edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1312edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
1313edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mCurrentState.orientation != orientation) {
1314edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (uint32_t(orientation)<=eOrientation270 || orientation==42) {
131521230c6410bdab13cd2bd274da54b1e4061b6035Jeff Brown            mCurrentState.orientationFlags = flags;
1316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mCurrentState.orientation = orientation;
1317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            setTransactionFlags(eTransactionNeeded);
1318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mTransactionCV.wait(mStateLock);
1319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
1320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            orientation = BAD_VALUE;
1321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1323edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return orientation;
1324edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1325edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
13260ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopiansp<ISurface> SurfaceFlinger::createSurface(
13270ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        ISurfaceComposerClient::surface_data_t* params,
13280ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const String8& name,
13290ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const sp<Client>& client,
1330edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        DisplayID d, uint32_t w, uint32_t h, PixelFormat format,
1331edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t flags)
1332edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1333076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBaseClient> layer;
1334a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    sp<ISurface> surfaceHandle;
13356e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian
13366e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    if (int32_t(w|h) < 0) {
13376e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian        LOGE("createSurface() failed, w or h is negative (w=%d, h=%d)",
13386e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian                int(w), int(h));
13396e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian        return surfaceHandle;
13406e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    }
13418b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
1342edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    //LOGD("createSurface for pid %d (%d x %d)", pid, w, h);
1343b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<Layer> normalLayer;
1344edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (flags & eFXSurfaceMask) {
1345edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceNormal:
1346a5529c8778c2f407f482fc12165aeb76c0f505c2Mathias Agopian            normalLayer = createNormalSurface(client, d, w, h, flags, format);
1347a5529c8778c2f407f482fc12165aeb76c0f505c2Mathias Agopian            layer = normalLayer;
1348edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
1349edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceBlur:
13501293a8eb567fd63c072a6970fa9dcf37d076059fMathias Agopian            // for now we treat Blur as Dim, until we can implement it
13511293a8eb567fd63c072a6970fa9dcf37d076059fMathias Agopian            // efficiently.
1352edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceDim:
135396f0819f81293076e652792794a961543e6750d7Mathias Agopian            layer = createDimSurface(client, d, w, h, flags);
1354edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
1355f171ab6da9cf9793093e50947aacdab8f2b0c9b2Mathias Agopian        case eFXSurfaceScreenshot:
1356f171ab6da9cf9793093e50947aacdab8f2b0c9b2Mathias Agopian            layer = createScreenshotSurface(client, d, w, h, flags);
1357f171ab6da9cf9793093e50947aacdab8f2b0c9b2Mathias Agopian            break;
1358edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1359edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1360076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (layer != 0) {
136196f0819f81293076e652792794a961543e6750d7Mathias Agopian        layer->initStates(w, h, flags);
1362285dbde2e0cd0057be070ded3be8f5f453147edcMathias Agopian        layer->setName(name);
136396f0819f81293076e652792794a961543e6750d7Mathias Agopian        ssize_t token = addClientLayer(client, layer);
1364b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1365edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        surfaceHandle = layer->getSurface();
13668b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber        if (surfaceHandle != 0) {
136796f0819f81293076e652792794a961543e6750d7Mathias Agopian            params->token = token;
1368a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            params->identity = layer->getIdentity();
1369b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            if (normalLayer != 0) {
1370b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian                Mutex::Autolock _l(mStateLock);
1371a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                mLayerMap.add(layer->getSurfaceBinder(), normalLayer);
1372b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            }
13731c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        }
1374b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
137596f0819f81293076e652792794a961543e6750d7Mathias Agopian        setTransactionFlags(eTransactionNeeded);
1376edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1377edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1378edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return surfaceHandle;
1379edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1380edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1381b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<Layer> SurfaceFlinger::createNormalSurface(
1382f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        const sp<Client>& client, DisplayID display,
138396f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags,
13841c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        PixelFormat& format)
1385edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1386edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize the surfaces
1387edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (format) { // TODO: take h/w into account
1388edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSPARENT:
1389edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSLUCENT:
1390edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        format = PIXEL_FORMAT_RGBA_8888;
1391edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1392edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_OPAQUE:
1393a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888
1394a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian        format = PIXEL_FORMAT_RGB_565;
1395a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#else
13968f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian        format = PIXEL_FORMAT_RGBX_8888;
1397a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif
1398edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1399edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1400edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1401a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888
1402a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian    if (format == PIXEL_FORMAT_RGBX_8888)
1403a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian        format = PIXEL_FORMAT_RGBA_8888;
1404a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif
1405a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian
140696f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<Layer> layer = new Layer(this, display, client);
1407f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian    status_t err = layer->setBuffers(w, h, format, flags);
140896f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (LIKELY(err != NO_ERROR)) {
1409edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        LOGE("createNormalSurfaceLocked() failed (%s)", strerror(-err));
1410076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        layer.clear();
1411edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1412edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1413edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1414edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1415b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<LayerDim> SurfaceFlinger::createDimSurface(
1416f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        const sp<Client>& client, DisplayID display,
141796f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags)
1418edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
141996f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<LayerDim> layer = new LayerDim(this, display, client);
1420f171ab6da9cf9793093e50947aacdab8f2b0c9b2Mathias Agopian    return layer;
1421f171ab6da9cf9793093e50947aacdab8f2b0c9b2Mathias Agopian}
1422f171ab6da9cf9793093e50947aacdab8f2b0c9b2Mathias Agopian
1423f171ab6da9cf9793093e50947aacdab8f2b0c9b2Mathias Agopiansp<LayerScreenshot> SurfaceFlinger::createScreenshotSurface(
1424f171ab6da9cf9793093e50947aacdab8f2b0c9b2Mathias Agopian        const sp<Client>& client, DisplayID display,
1425f171ab6da9cf9793093e50947aacdab8f2b0c9b2Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags)
1426f171ab6da9cf9793093e50947aacdab8f2b0c9b2Mathias Agopian{
1427f171ab6da9cf9793093e50947aacdab8f2b0c9b2Mathias Agopian    sp<LayerScreenshot> layer = new LayerScreenshot(this, display, client);
1428f171ab6da9cf9793093e50947aacdab8f2b0c9b2Mathias Agopian    status_t err = layer->capture();
1429f171ab6da9cf9793093e50947aacdab8f2b0c9b2Mathias Agopian    if (err != NO_ERROR) {
1430f171ab6da9cf9793093e50947aacdab8f2b0c9b2Mathias Agopian        layer.clear();
1431f171ab6da9cf9793093e50947aacdab8f2b0c9b2Mathias Agopian        LOGW("createScreenshotSurface failed (%s)", strerror(-err));
1432f171ab6da9cf9793093e50947aacdab8f2b0c9b2Mathias Agopian    }
1433edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1434edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1435edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
143696f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeSurface(const sp<Client>& client, SurfaceID sid)
14379a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
14389a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    /*
14399a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     * called by the window manager, when a surface should be marked for
14409a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     * destruction.
14418b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber     *
14420aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * The surface is removed from the current and drawing lists, but placed
14430aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * in the purgatory queue, so it's not destroyed right-away (we need
14440aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * to wait for all client's references to go away first).
14459a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     */
14469a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
144748d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    status_t err = NAME_NOT_FOUND;
14480aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian    Mutex::Autolock _l(mStateLock);
144996f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<LayerBaseClient> layer = client->getLayerUser(sid);
145048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    if (layer != 0) {
145148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        err = purgatorizeLayer_l(layer);
145248d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        if (err == NO_ERROR) {
145348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian            setTransactionFlags(eTransactionNeeded);
145448d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        }
14559a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    }
14569a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return err;
14579a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
14589a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
1459ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopianstatus_t SurfaceFlinger::destroySurface(const wp<LayerBaseClient>& layer)
1460edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1461759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian    // called by ~ISurface() when all references are gone
1462ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    status_t err = NO_ERROR;
1463ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    sp<LayerBaseClient> l(layer.promote());
1464ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    if (l != NULL) {
1465ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        Mutex::Autolock _l(mStateLock);
1466ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        err = removeLayer_l(l);
1467ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        if (err == NAME_NOT_FOUND) {
1468ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // The surface wasn't in the current list, which means it was
1469ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // removed already, which means it is in the purgatory,
1470ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // and need to be removed from there.
1471ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            ssize_t idx = mLayerPurgatory.remove(l);
1472ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            LOGE_IF(idx < 0,
1473ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian                    "layer=%p is not in the purgatory list", l.get());
1474f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        }
1475ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        LOGE_IF(err<0 && err != NAME_NOT_FOUND,
1476ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian                "error removing layer=%p (%s)", l.get(), strerror(-err));
1477ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    }
1478ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    return err;
1479edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1480edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1481698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopianuint32_t SurfaceFlinger::setClientStateLocked(
148296f0819f81293076e652792794a961543e6750d7Mathias Agopian        const sp<Client>& client,
1483698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const layer_state_t& s)
1484edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1485edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t flags = 0;
1486698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    sp<LayerBaseClient> layer(client->getLayerUser(s.surface));
1487698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    if (layer != 0) {
1488698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const uint32_t what = s.what;
1489698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & ePositionChanged) {
1490698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setPosition(s.x, s.y))
1491698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1492698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1493698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eLayerChanged) {
1494698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
1495698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setLayer(s.z)) {
1496698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                mCurrentState.layersSortedByZ.removeAt(idx);
1497698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                mCurrentState.layersSortedByZ.add(layer);
1498698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                // we need traversal (state changed)
1499698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                // AND transaction (list changed)
1500698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTransactionNeeded|eTraversalNeeded;
1501edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1502698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1503698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eSizeChanged) {
1504698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setSize(s.w, s.h)) {
1505698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1506698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                mResizeTransationPending = true;
1507edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1508edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1509698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eAlphaChanged) {
1510698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f)))
1511698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1512698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1513698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eMatrixChanged) {
1514698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setMatrix(s.matrix))
1515698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1516698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1517698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eTransparentRegionChanged) {
1518698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setTransparentRegionHint(s.transparentRegion))
1519698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1520698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1521698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eVisibilityChanged) {
1522698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setFlags(s.flags, s.mask))
1523698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1524698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1525edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1526698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    return flags;
1527edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1528edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1529edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::screenReleased(int dpy)
1530edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1531edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // this may be called by a signal handler, we can't do too much in here
1532edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    android_atomic_or(eConsoleReleased, &mConsoleSignals);
1533edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    signalEvent();
1534edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1535edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1536edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::screenAcquired(int dpy)
1537edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1538edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // this may be called by a signal handler, we can't do too much in here
1539edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    android_atomic_or(eConsoleAcquired, &mConsoleSignals);
1540edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    signalEvent();
1541edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1542edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1543edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
1544edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
15451d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling    const size_t SIZE = 4096;
1546edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char buffer[SIZE];
1547edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    String8 result;
154899b49840d309727678b77403d6cc9f920111623fMathias Agopian
154999b49840d309727678b77403d6cc9f920111623fMathias Agopian    if (!PermissionCache::checkCallingPermission(sDump)) {
1550edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        snprintf(buffer, SIZE, "Permission Denial: "
1551edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                "can't dump SurfaceFlinger from pid=%d, uid=%d\n",
1552edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                IPCThreadState::self()->getCallingPid(),
1553edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                IPCThreadState::self()->getCallingUid());
1554edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        result.append(buffer);
1555edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
15569795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
15579795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // figure out if we're stuck somewhere
15589795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const nsecs_t now = systemTime();
15599795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const nsecs_t inSwapBuffers(mDebugInSwapBuffers);
15609795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const nsecs_t inTransaction(mDebugInTransaction);
15619795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0;
15629795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0;
15639795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
15649795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // Try to get the main lock, but don't insist if we can't
15659795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // (this would indicate SF is stuck, but we want to be able to
15669795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // print something in dumpsys).
15679795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        int retry = 3;
15689795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        while (mStateLock.tryLock()<0 && --retry>=0) {
15699795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            usleep(1000000);
15709795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
15719795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const bool locked(retry >= 0);
15729795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (!locked) {
15738b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber            snprintf(buffer, SIZE,
15749795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "SurfaceFlinger appears to be unresponsive, "
15759795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "dumping anyways (no locks held)\n");
15769795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            result.append(buffer);
15779795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
15789795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
157948b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        /*
158048b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian         * Dump the visible layer list
158148b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian         */
1582edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
1583edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const size_t count = currentLayers.size();
158448b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        snprintf(buffer, SIZE, "Visible layers (count = %d)\n", count);
158548b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        result.append(buffer);
1586edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (size_t i=0 ; i<count ; i++) {
15871b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            const sp<LayerBase>& layer(currentLayers[i]);
15881b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            layer->dump(result, buffer, SIZE);
15891b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            const Layer::State& s(layer->drawingState());
1590edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            s.transparentRegion.dump(result, "transparentRegion");
1591edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->transparentRegionScreen.dump(result, "transparentRegionScreen");
1592edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->visibleRegionScreen.dump(result, "visibleRegionScreen");
1593edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
15941b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
159548b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        /*
159648b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian         * Dump the layers in the purgatory
159748b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian         */
159848b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
159948b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        const size_t purgatorySize =  mLayerPurgatory.size();
160048b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        snprintf(buffer, SIZE, "Purgatory state (%d entries)\n", purgatorySize);
160148b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        result.append(buffer);
160248b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        for (size_t i=0 ; i<purgatorySize ; i++) {
160348b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian            const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
160448b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian            layer->shortDump(result, buffer, SIZE);
160548b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        }
160648b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
160748b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        /*
160848b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian         * Dump SurfaceFlinger global state
160948b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian         */
161048b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
1611ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian        snprintf(buffer, SIZE, "SurfaceFlinger global state:\n");
161248b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        result.append(buffer);
1613ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian
1614ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian        const GLExtensions& extensions(GLExtensions::getInstance());
1615ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian        snprintf(buffer, SIZE, "GLES: %s, %s, %s\n",
1616ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian                extensions.getVendor(),
1617ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian                extensions.getRenderer(),
1618ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian                extensions.getVersion());
1619ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian        result.append(buffer);
1620ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian        snprintf(buffer, SIZE, "EXTS: %s\n", extensions.getExtension());
1621ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian        result.append(buffer);
1622ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian
1623edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mWormholeRegion.dump(result, "WormholeRegion");
1624edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const DisplayHardware& hw(graphicPlane(0).displayHardware());
1625edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        snprintf(buffer, SIZE,
1626edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                "  display frozen: %s, freezeCount=%d, orientation=%d, canDraw=%d\n",
1627edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mFreezeDisplay?"yes":"no", mFreezeCount,
1628edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mCurrentState.orientation, hw.canDraw());
1629edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        result.append(buffer);
16309795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        snprintf(buffer, SIZE,
16319795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                "  last eglSwapBuffers() time: %f us\n"
16329795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                "  last transaction time     : %f us\n",
16339795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                mLastSwapBufferTime/1000.0, mLastTransactionTime/1000.0);
16349795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        result.append(buffer);
16351b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
16369795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (inSwapBuffersDuration || !locked) {
16379795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            snprintf(buffer, SIZE, "  eglSwapBuffers time: %f us\n",
16389795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    inSwapBuffersDuration/1000.0);
16399795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            result.append(buffer);
16409795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
16411b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
16429795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (inTransactionDuration || !locked) {
16439795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            snprintf(buffer, SIZE, "  transaction time: %f us\n",
16449795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    inTransactionDuration/1000.0);
16459795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            result.append(buffer);
16469795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
16471b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
164848b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        /*
164948b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian         * Dump HWComposer state
165048b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian         */
165173d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian        HWComposer& hwc(hw.getHwComposer());
165273d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian        snprintf(buffer, SIZE, "  h/w composer %s and %s\n",
165373d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian                hwc.initCheck()==NO_ERROR ? "present" : "not present",
165453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                (mDebugDisableHWC || mDebugRegion) ? "disabled" : "enabled");
165573d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian        result.append(buffer);
165622da60c3e64cd57535cbba063c07127814a2b52fMathias Agopian        hwc.dump(result, buffer, SIZE, mVisibleLayersSortedByZ);
165773d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian
165848b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        /*
165948b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian         * Dump gralloc state
166048b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian         */
16613330b203039dea366d4981db1408a460134b2d2cMathias Agopian        const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
1662076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        alloc.dump(result);
16631d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling        hw.dump(result);
16649795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
16659795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (locked) {
16669795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            mStateLock.unlock();
16679795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
1668edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1669edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    write(fd, result.string(), result.size());
1670edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1671edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1672edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1673edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::onTransact(
1674edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
1675edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1676edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (code) {
1677edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case CREATE_CONNECTION:
1678698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        case SET_TRANSACTION_STATE:
1679edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case SET_ORIENTATION:
1680edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case FREEZE_DISPLAY:
1681edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case UNFREEZE_DISPLAY:
1682edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case BOOT_FINISHED:
168359119e658a12279e8fff508f8773843de2d90917Mathias Agopian        case TURN_ELECTRON_BEAM_OFF:
16849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        case TURN_ELECTRON_BEAM_ON:
1685edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        {
1686edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // codes that require permission check
1687edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            IPCThreadState* ipc = IPCThreadState::self();
1688edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int pid = ipc->getCallingPid();
1689a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian            const int uid = ipc->getCallingUid();
169099b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
169199b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) {
1692375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                LOGE("Permission Denial: "
1693375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                        "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
1694375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                return PERMISSION_DENIED;
1695edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
16961b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
16971b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
16981b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        case CAPTURE_SCREEN:
16991b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
17001b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            // codes that require permission check
17011b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
17021b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int pid = ipc->getCallingPid();
17031b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int uid = ipc->getCallingUid();
170499b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
170599b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) {
17061b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                LOGE("Permission Denial: "
17071b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                        "can't read framebuffer pid=%d, uid=%d", pid, uid);
17081b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                return PERMISSION_DENIED;
17091b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            }
17101b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
1711edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1712edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
17131b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
1714edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
1715edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
1716b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        CHECK_INTERFACE(ISurfaceComposer, data, reply);
171799b49840d309727678b77403d6cc9f920111623fMathias Agopian        if (UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) {
1718375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
1719375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int pid = ipc->getCallingPid();
1720375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int uid = ipc->getCallingUid();
1721375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            LOGE("Permission Denial: "
1722375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                    "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
1723edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return PERMISSION_DENIED;
1724edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1725edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int n;
1726edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        switch (code) {
172701b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian            case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE
172835b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian            case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE
1729edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1730edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1002:  // SHOW_UPDATES
1731edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                n = data.readInt32();
1732edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDebugRegion = n ? n : (mDebugRegion ? 0 : 1);
173353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
173453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
1735edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1736edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1003:  // SHOW_BACKGROUND
1737edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                n = data.readInt32();
1738edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDebugBackground = n ? 1 : 0;
1739edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1740edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1004:{ // repaint everything
174153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
1742cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
1743cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            }
1744cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            case 1005:{ // force transaction
1745cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
1746cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
1747edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
174835b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian            case 1006:{ // enable/disable GraphicLog
174935b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian                int enabled = data.readInt32();
175035b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian                GraphicLog::getInstance().setEnabled(enabled);
175135b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian                return NO_ERROR;
175235b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian            }
1753edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1007: // set mFreezeCount
1754edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mFreezeCount = data.readInt32();
17550408772e34931351d062f2088b611325ddaa6cdbMathias Agopian                mFreezeDisplayTime = 0;
1756edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
175753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian            case 1008:  // toggle use of hw composer
175853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                n = data.readInt32();
175953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                mDebugDisableHWC = n ? 1 : 0;
176053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
176153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
176253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                return NO_ERROR;
1763a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian            case 1009:  // toggle use of transform hint
1764a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                n = data.readInt32();
1765a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                mDebugDisableTransformHint = n ? 1 : 0;
1766a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                invalidateHwcGeometry();
1767a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                repaintEverything();
1768a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                return NO_ERROR;
1769edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1010:  // interrogate.
177001b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian                reply->writeInt32(0);
1771edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(0);
1772edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(mDebugRegion);
1773edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(mDebugBackground);
1774edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1775edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1013: {
1776edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                Mutex::Autolock _l(mStateLock);
1777edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                const DisplayHardware& hw(graphicPlane(0).displayHardware());
1778edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(hw.getPageFlipCount());
1779edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1780edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return NO_ERROR;
1781edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1782edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1783edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return err;
1784edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1785edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
178653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopianvoid SurfaceFlinger::repaintEverything() {
178753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian    Mutex::Autolock _l(mStateLock);
178853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
178953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian    mDirtyRegion.set(hw.bounds()); // careful that's not thread-safe
179053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian    signalEvent();
179153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian}
179253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian
179359119e658a12279e8fff508f8773843de2d90917Mathias Agopian// ---------------------------------------------------------------------------
179459119e658a12279e8fff508f8773843de2d90917Mathias Agopian
1795f171ab6da9cf9793093e50947aacdab8f2b0c9b2Mathias Agopianstatus_t SurfaceFlinger::renderScreenToTexture(DisplayID dpy,
1796f171ab6da9cf9793093e50947aacdab8f2b0c9b2Mathias Agopian        GLuint* textureName, GLfloat* uOut, GLfloat* vOut)
1797f171ab6da9cf9793093e50947aacdab8f2b0c9b2Mathias Agopian{
1798f171ab6da9cf9793093e50947aacdab8f2b0c9b2Mathias Agopian    Mutex::Autolock _l(mStateLock);
1799f171ab6da9cf9793093e50947aacdab8f2b0c9b2Mathias Agopian    return renderScreenToTextureLocked(dpy, textureName, uOut, vOut);
1800f171ab6da9cf9793093e50947aacdab8f2b0c9b2Mathias Agopian}
1801f171ab6da9cf9793093e50947aacdab8f2b0c9b2Mathias Agopian
18029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::renderScreenToTextureLocked(DisplayID dpy,
18039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        GLuint* textureName, GLfloat* uOut, GLfloat* vOut)
180459119e658a12279e8fff508f8773843de2d90917Mathias Agopian{
180559119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
180659119e658a12279e8fff508f8773843de2d90917Mathias Agopian        return INVALID_OPERATION;
180759119e658a12279e8fff508f8773843de2d90917Mathias Agopian
180859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // get screen geometry
180959119e658a12279e8fff508f8773843de2d90917Mathias Agopian    const DisplayHardware& hw(graphicPlane(dpy).displayHardware());
181059119e658a12279e8fff508f8773843de2d90917Mathias Agopian    const uint32_t hw_w = hw.getWidth();
181159119e658a12279e8fff508f8773843de2d90917Mathias Agopian    const uint32_t hw_h = hw.getHeight();
181259119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLfloat u = 1;
181359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLfloat v = 1;
181459119e658a12279e8fff508f8773843de2d90917Mathias Agopian
181559119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // make sure to clear all GL error flags
181659119e658a12279e8fff508f8773843de2d90917Mathias Agopian    while ( glGetError() != GL_NO_ERROR ) ;
181759119e658a12279e8fff508f8773843de2d90917Mathias Agopian
181859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // create a FBO
181959119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLuint name, tname;
182059119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glGenTextures(1, &tname);
182159119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
18229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
18239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            hw_w, hw_h, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
182459119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (glGetError() != GL_NO_ERROR) {
1825015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian        while ( glGetError() != GL_NO_ERROR ) ;
182659119e658a12279e8fff508f8773843de2d90917Mathias Agopian        GLint tw = (2 << (31 - clz(hw_w)));
182759119e658a12279e8fff508f8773843de2d90917Mathias Agopian        GLint th = (2 << (31 - clz(hw_h)));
18289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
18299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian                tw, th, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
183059119e658a12279e8fff508f8773843de2d90917Mathias Agopian        u = GLfloat(hw_w) / tw;
183159119e658a12279e8fff508f8773843de2d90917Mathias Agopian        v = GLfloat(hw_h) / th;
183259119e658a12279e8fff508f8773843de2d90917Mathias Agopian    }
183359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glGenFramebuffersOES(1, &name);
183459119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
18359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES,
18369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0);
183759119e658a12279e8fff508f8773843de2d90917Mathias Agopian
18389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // redraw the screen entirely...
18399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glClearColor(0,0,0,1);
18409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glClear(GL_COLOR_BUFFER_BIT);
1841a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glMatrixMode(GL_MODELVIEW);
1842a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glLoadIdentity();
18439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
18449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const size_t count = layers.size();
18459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (size_t i=0 ; i<count ; ++i) {
18469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
18479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        layer->drawForSreenShot();
18489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
184959119e658a12279e8fff508f8773843de2d90917Mathias Agopian
18509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // back to main framebuffer
18519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
18529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_SCISSOR_TEST);
18539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDeleteFramebuffersOES(1, &name);
185459119e658a12279e8fff508f8773843de2d90917Mathias Agopian
18559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *textureName = tname;
18569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *uOut = u;
18579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *vOut = v;
18589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
18599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
186059119e658a12279e8fff508f8773843de2d90917Mathias Agopian
18619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// ---------------------------------------------------------------------------
186259119e658a12279e8fff508f8773843de2d90917Mathias Agopian
18639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::electronBeamOffAnimationImplLocked()
18649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
18659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // get screen geometry
18669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
18679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_w = hw.getWidth();
18689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_h = hw.getHeight();
1869a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    const Region screenBounds(hw.getBounds());
187059119e658a12279e8fff508f8773843de2d90917Mathias Agopian
18719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat u, v;
18729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLuint tname;
1873f171ab6da9cf9793093e50947aacdab8f2b0c9b2Mathias Agopian    status_t result = renderScreenToTextureLocked(0, &tname, &u, &v);
18749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (result != NO_ERROR) {
18759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return result;
18769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
187759119e658a12279e8fff508f8773843de2d90917Mathias Agopian
18789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat vtx[8];
1879a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    const GLfloat texCoords[4][2] = { {0,0}, {0,v}, {u,v}, {u,0} };
18809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
18819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
18829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
18839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
18849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
18859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
18869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glVertexPointer(2, GL_FLOAT, 0, vtx);
18879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
1888ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    /*
1889ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     * Texture coordinate mapping
1890ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *
1891ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *                 u
1892ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *    1 +----------+---+
1893ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |     |    |   |  image is inverted
1894ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |     V    |   |  w.r.t. the texture
1895ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *  1-v +----------+   |  coordinates
1896ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |              |
1897ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |              |
1898ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |              |
1899ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *    0 +--------------+
1900ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      0              1
1901ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *
1902ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     */
1903ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian
19049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class s_curve_interpolator {
19059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float nbFrames, s, v;
19069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
19079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        s_curve_interpolator(int nbFrames, float s)
19089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : nbFrames(1.0f / (nbFrames-1)), s(s),
19099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian          v(1.0f + expf(-s + 0.5f*s)) {
19109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
19119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float operator()(int f) {
19129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const float x = f * nbFrames;
19139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f;
19149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
19159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
19169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class v_stretch {
19189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
19199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
19209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        v_stretch(uint32_t hw_w, uint32_t hw_h)
19219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
19229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
19239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
19249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w + (hw_w * v);
19259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = hw_h - (hw_h * v);
19269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
19279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
1928ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[0] = x;         vtx[1] = y;
1929ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
1930ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
1931ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
19329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
19339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
19349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class h_stretch {
19369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
19379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
19389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        h_stretch(uint32_t hw_w, uint32_t hw_h)
19399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
194059119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
19419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
19429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w - (hw_w * v);
19439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = 1.0f;
19449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
19459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
1946ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[0] = x;         vtx[1] = y;
1947ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
1948ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
1949ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
19509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
19519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
19529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // the full animation is 24 frames
1954ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    char value[PROPERTY_VALUE_MAX];
1955ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    property_get("debug.sf.electron_frames", value, "24");
1956ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    int nbFrames = (atoi(value) + 1) >> 1;
1957ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    if (nbFrames <= 0) // just in case
1958ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian        nbFrames = 24;
1959ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian
19609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itr(nbFrames, 7.5f);
19619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itg(nbFrames, 8.0f);
19629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itb(nbFrames, 8.5f);
19639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    v_stretch vverts(hw_w, hw_h);
1965a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian
1966a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glMatrixMode(GL_TEXTURE);
1967a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glLoadIdentity();
1968a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glMatrixMode(GL_MODELVIEW);
1969a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glLoadIdentity();
1970a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian
19719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnable(GL_BLEND);
19729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBlendFunc(GL_ONE, GL_ONE);
19739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=0 ; i<nbFrames ; i++) {
19749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float x, y, w, h;
19759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vr = itr(i);
19769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vg = itg(i);
19779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vb = itb(i);
19789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // clear screen
19809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(1,1,1,1);
19819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
19829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glEnable(GL_TEXTURE_2D);
198359119e658a12279e8fff508f8773843de2d90917Mathias Agopian
19849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the red plane
19859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vr);
19869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(1,0,0,1);
19879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
19889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the green plane
19909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vg);
19919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,1,0,1);
19929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
19939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the blue plane
19959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vb);
19969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,0,1,1);
19979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
19989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the white highlight (we use the last vertices)
200059119e658a12279e8fff508f8773843de2d90917Mathias Agopian        glDisable(GL_TEXTURE_2D);
200159119e658a12279e8fff508f8773843de2d90917Mathias Agopian        glColorMask(1,1,1,1);
20029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColor4f(vg, vg, vg, 1);
20039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
20049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
20059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
20069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    h_stretch hverts(hw_w, hw_h);
20089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_BLEND);
20099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_TEXTURE_2D);
20109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
20119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=0 ; i<nbFrames ; i++) {
20129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float v = itg(i);
20139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hverts(vtx, v);
20149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
20159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColor4f(1-v, 1-v, 1-v, 1);
20169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
20179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
20189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
20199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
20219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnable(GL_SCISSOR_TEST);
20229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
20239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDeleteTextures(1, &tname);
2024a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    glDisable(GL_TEXTURE_2D);
20259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
20269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
20279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::electronBeamOnAnimationImplLocked()
20299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
20309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    status_t result = PERMISSION_DENIED;
20319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
20339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return INVALID_OPERATION;
20349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // get screen geometry
20379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
20389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_w = hw.getWidth();
20399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_h = hw.getHeight();
20409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const Region screenBounds(hw.bounds());
20419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat u, v;
20439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLuint tname;
20449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    result = renderScreenToTextureLocked(0, &tname, &u, &v);
20459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (result != NO_ERROR) {
20469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return result;
20479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
20489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat vtx[8];
20509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const GLfloat texCoords[4][2] = { {0,v}, {0,0}, {u,0}, {u,v} };
20519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
20529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
20539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
20549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
20559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
20569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
20579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glVertexPointer(2, GL_FLOAT, 0, vtx);
20589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class s_curve_interpolator {
20609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float nbFrames, s, v;
20619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
20629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        s_curve_interpolator(int nbFrames, float s)
20639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : nbFrames(1.0f / (nbFrames-1)), s(s),
20649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian          v(1.0f + expf(-s + 0.5f*s)) {
20659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
20669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float operator()(int f) {
20679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const float x = f * nbFrames;
20689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f;
20699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
20709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
20719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class v_stretch {
20739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
20749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
20759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        v_stretch(uint32_t hw_w, uint32_t hw_h)
20769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
207759119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
20789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
20799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w + (hw_w * v);
20809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = hw_h - (hw_h * v);
20819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
20829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
20839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[0] = x;         vtx[1] = y;
20849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
20859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
20869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
20879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
20889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
20899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class h_stretch {
20919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
20929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
20939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        h_stretch(uint32_t hw_w, uint32_t hw_h)
20949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
20959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
20969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
20979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w - (hw_w * v);
20989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = 1.0f;
20999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
21009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
21019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[0] = x;         vtx[1] = y;
21029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
21039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
21049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
21059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
21069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
21079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2108a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian    // the full animation is 12 frames
2109a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian    int nbFrames = 8;
21109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itr(nbFrames, 7.5f);
21119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itg(nbFrames, 8.0f);
21129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itb(nbFrames, 8.5f);
21139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    h_stretch hverts(hw_w, hw_h);
21159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_BLEND);
21169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_TEXTURE_2D);
21179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
21189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=nbFrames-1 ; i>=0 ; i--) {
21199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float v = itg(i);
21209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hverts(vtx, v);
21219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
21229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColor4f(1-v, 1-v, 1-v, 1);
21239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
21249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
21259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
21269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2127a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian    nbFrames = 4;
21289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    v_stretch vverts(hw_w, hw_h);
21299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnable(GL_BLEND);
21309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBlendFunc(GL_ONE, GL_ONE);
21319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=nbFrames-1 ; i>=0 ; i--) {
21329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float x, y, w, h;
21339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vr = itr(i);
21349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vg = itg(i);
21359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vb = itb(i);
213659119e658a12279e8fff508f8773843de2d90917Mathias Agopian
21379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // clear screen
213859119e658a12279e8fff508f8773843de2d90917Mathias Agopian        glColorMask(1,1,1,1);
21399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
21409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glEnable(GL_TEXTURE_2D);
21419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the red plane
21439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vr);
21449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(1,0,0,1);
21459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
21469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the green plane
21489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vg);
21499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,1,0,1);
21509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
21519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the blue plane
21539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vb);
21549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,0,1,1);
21559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
21569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
215859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    }
215959119e658a12279e8fff508f8773843de2d90917Mathias Agopian
21609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
21619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnable(GL_SCISSOR_TEST);
21629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
216359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glDeleteTextures(1, &tname);
2164a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    glDisable(GL_TEXTURE_2D);
216559119e658a12279e8fff508f8773843de2d90917Mathias Agopian
21669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
21679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
21689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// ---------------------------------------------------------------------------
21709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2171abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOffImplLocked(int32_t mode)
21729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
21739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    DisplayHardware& hw(graphicPlane(0).editDisplayHardware());
21749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (!hw.canDraw()) {
21759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // we're already off
21769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return NO_ERROR;
21779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
21787ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian
21797ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian    // turn off hwc while we're doing the animation
21807ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian    hw.getHwComposer().disable();
21817ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian    // and make sure to turn it back on (if needed) next time we compose
21827ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian    invalidateHwcGeometry();
21837ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian
2184abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    if (mode & ISurfaceComposer::eElectronBeamAnimationOff) {
2185abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        electronBeamOffAnimationImplLocked();
2186abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    }
2187abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian
2188abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    // always clear the whole screen at the end of the animation
2189abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    glClearColor(0,0,0,1);
2190abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    glDisable(GL_SCISSOR_TEST);
2191abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    glClear(GL_COLOR_BUFFER_BIT);
2192abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    glEnable(GL_SCISSOR_TEST);
2193abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    hw.flip( Region(hw.bounds()) );
2194abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian
2195015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian    return NO_ERROR;
219659119e658a12279e8fff508f8773843de2d90917Mathias Agopian}
219759119e658a12279e8fff508f8773843de2d90917Mathias Agopian
219859119e658a12279e8fff508f8773843de2d90917Mathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOff(int32_t mode)
219959119e658a12279e8fff508f8773843de2d90917Mathias Agopian{
220059119e658a12279e8fff508f8773843de2d90917Mathias Agopian    class MessageTurnElectronBeamOff : public MessageBase {
220159119e658a12279e8fff508f8773843de2d90917Mathias Agopian        SurfaceFlinger* flinger;
2202abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        int32_t mode;
220359119e658a12279e8fff508f8773843de2d90917Mathias Agopian        status_t result;
220459119e658a12279e8fff508f8773843de2d90917Mathias Agopian    public:
2205abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        MessageTurnElectronBeamOff(SurfaceFlinger* flinger, int32_t mode)
2206abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            : flinger(flinger), mode(mode), result(PERMISSION_DENIED) {
220759119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
220859119e658a12279e8fff508f8773843de2d90917Mathias Agopian        status_t getResult() const {
220959119e658a12279e8fff508f8773843de2d90917Mathias Agopian            return result;
221059119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
221159119e658a12279e8fff508f8773843de2d90917Mathias Agopian        virtual bool handler() {
221259119e658a12279e8fff508f8773843de2d90917Mathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
2213abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            result = flinger->turnElectronBeamOffImplLocked(mode);
221459119e658a12279e8fff508f8773843de2d90917Mathias Agopian            return true;
221559119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
221659119e658a12279e8fff508f8773843de2d90917Mathias Agopian    };
221759119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2218abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    sp<MessageBase> msg = new MessageTurnElectronBeamOff(this, mode);
221959119e658a12279e8fff508f8773843de2d90917Mathias Agopian    status_t res = postMessageSync(msg);
222059119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (res == NO_ERROR) {
222159119e658a12279e8fff508f8773843de2d90917Mathias Agopian        res = static_cast<MessageTurnElectronBeamOff*>( msg.get() )->getResult();
22229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // work-around: when the power-manager calls us we activate the
22249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // animation. eventually, the "on" animation will be called
22259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // by the power-manager itself
2226abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        mElectronBeamAnimationMode = mode;
222759119e658a12279e8fff508f8773843de2d90917Mathias Agopian    }
222859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    return res;
222959119e658a12279e8fff508f8773843de2d90917Mathias Agopian}
223059119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
2232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2233abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOnImplLocked(int32_t mode)
22349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
22359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    DisplayHardware& hw(graphicPlane(0).editDisplayHardware());
22369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (hw.canDraw()) {
22379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // we're already on
22389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return NO_ERROR;
22399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
2240abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    if (mode & ISurfaceComposer::eElectronBeamAnimationOn) {
2241abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        electronBeamOnAnimationImplLocked();
2242abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    }
2243a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian
2244a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian    // make sure to redraw the whole screen when the animation is done
2245a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian    mDirtyRegion.set(hw.bounds());
2246a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian    signalEvent();
2247a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian
2248015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian    return NO_ERROR;
22499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
22509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOn(int32_t mode)
22529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
22539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class MessageTurnElectronBeamOn : public MessageBase {
22549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        SurfaceFlinger* flinger;
2255abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        int32_t mode;
22569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        status_t result;
22579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
2258abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        MessageTurnElectronBeamOn(SurfaceFlinger* flinger, int32_t mode)
2259abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            : flinger(flinger), mode(mode), result(PERMISSION_DENIED) {
22609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
22619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        status_t getResult() const {
22629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return result;
22639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
22649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        virtual bool handler() {
22659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
2266abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            result = flinger->turnElectronBeamOnImplLocked(mode);
22679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return true;
22689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
22699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
22709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2271abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    postMessageAsync( new MessageTurnElectronBeamOn(this, mode) );
22729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
22739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
22749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// ---------------------------------------------------------------------------
22769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
227774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopianstatus_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy,
227874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        sp<IMemoryHeap>* heap,
227974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t* w, uint32_t* h, PixelFormat* f,
2280bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t sw, uint32_t sh,
2281bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ, uint32_t maxLayerZ)
228274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{
228374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    status_t result = PERMISSION_DENIED;
228474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
228574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // only one display supported for now
228674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
228774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return BAD_VALUE;
228874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
228974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
229074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return INVALID_OPERATION;
229174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
229274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // get screen geometry
229374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const DisplayHardware& hw(graphicPlane(dpy).displayHardware());
229474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const uint32_t hw_w = hw.getWidth();
229574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const uint32_t hw_h = hw.getHeight();
229674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
229774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    if ((sw > hw_w) || (sh > hw_h))
229874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return BAD_VALUE;
229974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
230074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    sw = (!sw) ? hw_w : sw;
230174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    sh = (!sh) ? hw_h : sh;
230274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const size_t size = sw * sh * 4;
230374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
23041c71a47a6db679a3212f0c99e14f330d6da500faMathias Agopian    //LOGD("screenshot: sw=%d, sh=%d, minZ=%d, maxZ=%d",
23051c71a47a6db679a3212f0c99e14f330d6da500faMathias Agopian    //        sw, sh, minLayerZ, maxLayerZ);
2306c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
230774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // make sure to clear all GL error flags
230874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    while ( glGetError() != GL_NO_ERROR ) ;
230974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
231074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // create a FBO
231174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    GLuint name, tname;
231274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glGenRenderbuffersOES(1, &tname);
231374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindRenderbufferOES(GL_RENDERBUFFER_OES, tname);
231474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA8_OES, sw, sh);
231574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glGenFramebuffersOES(1, &name);
231674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
231774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES,
231874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, tname);
231974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
232074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
2321c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
232274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    if (status == GL_FRAMEBUFFER_COMPLETE_OES) {
232374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
232474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // invert everything, b/c glReadPixel() below will invert the FB
232574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glViewport(0, 0, sw, sh);
2326f653b897a449e10d6cbfb6e0812f7b0bb02d6482Mathias Agopian        glScissor(0, 0, sw, sh);
2327ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian        glEnable(GL_SCISSOR_TEST);
232874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_PROJECTION);
232974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glPushMatrix();
233074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glLoadIdentity();
2331ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian        glOrthof(0, hw_w, hw_h, 0, 0, 1);
233274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_MODELVIEW);
233374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
233474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // redraw the screen entirely...
233574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glClearColor(0,0,0,1);
233674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
2337f653b897a449e10d6cbfb6e0812f7b0bb02d6482Mathias Agopian
23389575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        const LayerVector& layers(mDrawingState.layersSortedByZ);
23399575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        const size_t count = layers.size();
234074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        for (size_t i=0 ; i<count ; ++i) {
234174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            const sp<LayerBase>& layer(layers[i]);
2342b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian            const uint32_t flags = layer->drawingState().flags;
2343b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian            if (!(flags & ISurfaceComposer::eLayerHidden)) {
2344b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                const uint32_t z = layer->drawingState().z;
2345b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                if (z >= minLayerZ && z <= maxLayerZ) {
2346b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                    layer->drawForSreenShot();
2347b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                }
2348bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian            }
234974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        }
235074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
235174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // XXX: this is needed on tegra
2352ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian        glEnable(GL_SCISSOR_TEST);
235374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glScissor(0, 0, sw, sh);
235474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
235574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // check for errors and return screen capture
235674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        if (glGetError() != GL_NO_ERROR) {
235774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // error while rendering
235874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            result = INVALID_OPERATION;
235974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        } else {
236074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // allocate shared memory large enough to hold the
236174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // screen capture
236274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            sp<MemoryHeapBase> base(
236374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    new MemoryHeapBase(size, 0, "screen-capture") );
236474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            void* const ptr = base->getBase();
236574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            if (ptr) {
236674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                // capture the screen with glReadPixels()
236774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                glReadPixels(0, 0, sw, sh, GL_RGBA, GL_UNSIGNED_BYTE, ptr);
236874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                if (glGetError() == GL_NO_ERROR) {
236974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *heap = base;
237074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *w = sw;
237174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *h = sh;
237274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *f = PIXEL_FORMAT_RGBA_8888;
237374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    result = NO_ERROR;
237474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                }
237574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            } else {
237674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                result = NO_MEMORY;
237774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            }
237874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        }
237974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glEnable(GL_SCISSOR_TEST);
238074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glViewport(0, 0, hw_w, hw_h);
238174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_PROJECTION);
238274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glPopMatrix();
238374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_MODELVIEW);
238474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    } else {
238574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        result = BAD_VALUE;
238674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    }
238774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
238874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // release FBO resources
238974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
239074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glDeleteRenderbuffersOES(1, &tname);
239174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glDeleteFramebuffersOES(1, &name);
2392e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian
2393e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian    hw.compositionComplete();
2394e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian
23951c71a47a6db679a3212f0c99e14f330d6da500faMathias Agopian    // LOGD("screenshot: result = %s", result<0 ? strerror(result) : "OK");
2396c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
239774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    return result;
239874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian}
239974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
240074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
24011b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopianstatus_t SurfaceFlinger::captureScreen(DisplayID dpy,
24021b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        sp<IMemoryHeap>* heap,
240374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t* width, uint32_t* height, PixelFormat* format,
2404bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t sw, uint32_t sh,
2405bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ, uint32_t maxLayerZ)
24061b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian{
24071b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    // only one display supported for now
24081b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
24091b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        return BAD_VALUE;
24101b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
24111b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
24121b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        return INVALID_OPERATION;
24131b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
24141b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    class MessageCaptureScreen : public MessageBase {
24151b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        SurfaceFlinger* flinger;
24161b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        DisplayID dpy;
24171b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        sp<IMemoryHeap>* heap;
24181b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        uint32_t* w;
24191b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        uint32_t* h;
24201b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        PixelFormat* f;
242174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t sw;
242274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t sh;
2423bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ;
2424bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t maxLayerZ;
24251b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        status_t result;
24261b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    public:
24271b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        MessageCaptureScreen(SurfaceFlinger* flinger, DisplayID dpy,
242874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                sp<IMemoryHeap>* heap, uint32_t* w, uint32_t* h, PixelFormat* f,
2429bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                uint32_t sw, uint32_t sh,
2430bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                uint32_t minLayerZ, uint32_t maxLayerZ)
24311b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            : flinger(flinger), dpy(dpy),
2432bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              heap(heap), w(w), h(h), f(f), sw(sw), sh(sh),
2433bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              minLayerZ(minLayerZ), maxLayerZ(maxLayerZ),
2434bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              result(PERMISSION_DENIED)
24351b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
24361b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
24371b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        status_t getResult() const {
24381b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            return result;
24391b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
24401b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        virtual bool handler() {
24411b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
24421b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
24431b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            // if we have secure windows, never allow the screen capture
24441b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            if (flinger->mSecureFrameBuffer)
24451b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                return true;
24461b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
244774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            result = flinger->captureScreenImplLocked(dpy,
2448bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                    heap, w, h, f, sw, sh, minLayerZ, maxLayerZ);
24491b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
24501b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            return true;
24511b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
24521b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    };
24531b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
24541b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    sp<MessageBase> msg = new MessageCaptureScreen(this,
2455bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian            dpy, heap, width, height, format, sw, sh, minLayerZ, maxLayerZ);
24561b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    status_t res = postMessageSync(msg);
24571b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    if (res == NO_ERROR) {
24581b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        res = static_cast<MessageCaptureScreen*>( msg.get() )->getResult();
24591b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    }
24601b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    return res;
24611b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian}
24621b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
24631b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// ---------------------------------------------------------------------------
24641b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
2465b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<Layer> SurfaceFlinger::getLayer(const sp<ISurface>& sur) const
2466edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2467b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<Layer> result;
2468b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    Mutex::Autolock _l(mStateLock);
2469b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    result = mLayerMap.valueFor( sur->asBinder() ).promote();
2470b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return result;
2471b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
24727303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
2473b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// ---------------------------------------------------------------------------
247496f0819f81293076e652792794a961543e6750d7Mathias Agopian
2475b7e930db175c192464cebdeb49eb56cf6dd60114Mathias AgopianClient::Client(const sp<SurfaceFlinger>& flinger)
2476b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    : mFlinger(flinger), mNameGenerator(1)
2477b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{
2478edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2479edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
248096f0819f81293076e652792794a961543e6750d7Mathias AgopianClient::~Client()
248196f0819f81293076e652792794a961543e6750d7Mathias Agopian{
248296f0819f81293076e652792794a961543e6750d7Mathias Agopian    const size_t count = mLayers.size();
248396f0819f81293076e652792794a961543e6750d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
248496f0819f81293076e652792794a961543e6750d7Mathias Agopian        sp<LayerBaseClient> layer(mLayers.valueAt(i).promote());
248596f0819f81293076e652792794a961543e6750d7Mathias Agopian        if (layer != 0) {
248696f0819f81293076e652792794a961543e6750d7Mathias Agopian            mFlinger->removeLayer(layer);
248796f0819f81293076e652792794a961543e6750d7Mathias Agopian        }
2488edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2489edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2490076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
249196f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t Client::initCheck() const {
2492b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return NO_ERROR;
2493edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2494076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
24954f113740180b6512b43723c4728f262882dc9b45Mathias Agopiansize_t Client::attachLayer(const sp<LayerBaseClient>& layer)
2496edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
24974f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    Mutex::Autolock _l(mLock);
24984f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    size_t name = mNameGenerator++;
249996f0819f81293076e652792794a961543e6750d7Mathias Agopian    mLayers.add(name, layer);
250096f0819f81293076e652792794a961543e6750d7Mathias Agopian    return name;
2501edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2502edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2503b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianvoid Client::detachLayer(const LayerBaseClient* layer)
250496f0819f81293076e652792794a961543e6750d7Mathias Agopian{
25054f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    Mutex::Autolock _l(mLock);
250696f0819f81293076e652792794a961543e6750d7Mathias Agopian    // we do a linear search here, because this doesn't happen often
250796f0819f81293076e652792794a961543e6750d7Mathias Agopian    const size_t count = mLayers.size();
250896f0819f81293076e652792794a961543e6750d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
250996f0819f81293076e652792794a961543e6750d7Mathias Agopian        if (mLayers.valueAt(i) == layer) {
251096f0819f81293076e652792794a961543e6750d7Mathias Agopian            mLayers.removeItemsAt(i, 1);
251196f0819f81293076e652792794a961543e6750d7Mathias Agopian            break;
251296f0819f81293076e652792794a961543e6750d7Mathias Agopian        }
251396f0819f81293076e652792794a961543e6750d7Mathias Agopian    }
251496f0819f81293076e652792794a961543e6750d7Mathias Agopian}
25154f113740180b6512b43723c4728f262882dc9b45Mathias Agopiansp<LayerBaseClient> Client::getLayerUser(int32_t i) const
25164f113740180b6512b43723c4728f262882dc9b45Mathias Agopian{
25174f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    Mutex::Autolock _l(mLock);
2518076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBaseClient> lbc;
25194f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    wp<LayerBaseClient> layer(mLayers.valueFor(i));
252096f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (layer != 0) {
252196f0819f81293076e652792794a961543e6750d7Mathias Agopian        lbc = layer.promote();
252296f0819f81293076e652792794a961543e6750d7Mathias Agopian        LOGE_IF(lbc==0, "getLayerUser(name=%d) is dead", int(i));
2523076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
2524076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return lbc;
2525edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2526edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2527a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
2528a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianstatus_t Client::onTransact(
2529a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
2530a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian{
2531a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // these must be checked
2532a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     IPCThreadState* ipc = IPCThreadState::self();
2533a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     const int pid = ipc->getCallingPid();
2534a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     const int uid = ipc->getCallingUid();
2535a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     const int self_pid = getpid();
2536a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     if (UNLIKELY(pid != self_pid && uid != AID_GRAPHICS && uid != 0)) {
2537a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian         // we're called from a different process, do the real check
253899b49840d309727678b77403d6cc9f920111623fMathias Agopian         if (!PermissionCache::checkCallingPermission(sAccessSurfaceFlinger))
2539a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian         {
2540a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian             LOGE("Permission Denial: "
2541a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                     "can't openGlobalTransaction pid=%d, uid=%d", pid, uid);
2542a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian             return PERMISSION_DENIED;
2543a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian         }
2544a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     }
2545a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     return BnSurfaceComposerClient::onTransact(code, data, reply, flags);
2546edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2547a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
2548a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
254996f0819f81293076e652792794a961543e6750d7Mathias Agopiansp<ISurface> Client::createSurface(
25500ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        ISurfaceComposerClient::surface_data_t* params,
2551b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        const String8& name,
2552b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
2553edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t flags)
2554edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2555b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    /*
2556a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     * createSurface must be called from the GL thread so that it can
2557a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     * have access to the GL context.
2558b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     */
2559b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
2560a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    class MessageCreateSurface : public MessageBase {
2561a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        sp<ISurface> result;
2562a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        SurfaceFlinger* flinger;
2563a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        ISurfaceComposerClient::surface_data_t* params;
2564a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        Client* client;
2565a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        const String8& name;
2566a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        DisplayID display;
2567a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        uint32_t w, h;
2568a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        PixelFormat format;
2569a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        uint32_t flags;
2570a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    public:
2571a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        MessageCreateSurface(SurfaceFlinger* flinger,
2572a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                ISurfaceComposerClient::surface_data_t* params,
2573a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                const String8& name, Client* client,
2574a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
2575a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                uint32_t flags)
2576a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            : flinger(flinger), params(params), client(client), name(name),
2577a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian              display(display), w(w), h(h), format(format), flags(flags)
2578a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        {
2579579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        }
2580a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        sp<ISurface> getResult() const { return result; }
2581a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        virtual bool handler() {
2582a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            result = flinger->createSurface(params, name, client,
2583a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                    display, w, h, format, flags);
2584a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            return true;
2585b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        }
2586a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    };
2587b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
2588a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    sp<MessageBase> msg = new MessageCreateSurface(mFlinger.get(),
2589a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            params, name, this, display, w, h, format, flags);
2590a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    mFlinger->postMessageSync(msg);
2591a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    return static_cast<MessageCreateSurface*>( msg.get() )->getResult();
2592b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
2593a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianstatus_t Client::destroySurface(SurfaceID sid) {
2594a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    return mFlinger->removeSurface(this, sid);
2595b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
2596b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
2597b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// ---------------------------------------------------------------------------
2598edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
25999a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::GraphicBufferAlloc() {}
26009a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
26019a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::~GraphicBufferAlloc() {}
26029a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
26039a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h,
2604d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        PixelFormat format, uint32_t usage, status_t* error) {
26059a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(w, h, format, usage));
26069a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    status_t err = graphicBuffer->initCheck();
2607d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian    *error = err;
2608a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (err != 0 || graphicBuffer->handle == 0) {
2609d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        if (err == NO_MEMORY) {
2610d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian            GraphicBuffer::dumpAllocationsToSystemLog();
2611d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        }
2612a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        LOGE("GraphicBufferAlloc::createGraphicBuffer(w=%d, h=%d) "
2613a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian             "failed (%s), handle=%p",
2614a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                w, h, strerror(-err), graphicBuffer->handle);
26159a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis        return 0;
26169a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    }
26179a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    return graphicBuffer;
26189a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis}
26199a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
26209a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis// ---------------------------------------------------------------------------
26219a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
2622edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane::GraphicPlane()
2623edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    : mHw(0)
2624edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2625edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2626edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2627edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane::~GraphicPlane() {
2628edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    delete mHw;
2629edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2630edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2631edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool GraphicPlane::initialized() const {
2632edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return mHw ? true : false;
2633edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2634edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
26352b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianint GraphicPlane::getWidth() const {
26362b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    return mWidth;
2637edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2638edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
26392b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianint GraphicPlane::getHeight() const {
26402b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    return mHeight;
26412b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian}
26422b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
26432b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianvoid GraphicPlane::setDisplayHardware(DisplayHardware *hw)
26442b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian{
26452b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mHw = hw;
26462b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
26472b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    // initialize the display orientation transform.
26482b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    // it's a constant that should come from the display driver.
26492b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    int displayOrientation = ISurfaceComposer::eOrientationDefault;
26502b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    char property[PROPERTY_VALUE_MAX];
26512b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    if (property_get("ro.sf.hwrotation", property, NULL) > 0) {
26522b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        //displayOrientation
26532b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        switch (atoi(property)) {
26542b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        case 90:
26552b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            displayOrientation = ISurfaceComposer::eOrientation90;
26562b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            break;
26572b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        case 270:
26582b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            displayOrientation = ISurfaceComposer::eOrientation270;
26592b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            break;
26602b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        }
26612b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    }
26622b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
26632b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float w = hw->getWidth();
26642b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float h = hw->getHeight();
26652b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    GraphicPlane::orientationToTransfrom(displayOrientation, w, h,
26662b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            &mDisplayTransform);
26672b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    if (displayOrientation & ISurfaceComposer::eOrientationSwapMask) {
26682b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayWidth = h;
26692b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayHeight = w;
26702b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    } else {
26712b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayWidth = w;
26722b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayHeight = h;
26732b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    }
26742b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
26752b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    setOrientation(ISurfaceComposer::eOrientationDefault);
2676edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2677edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2678edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t GraphicPlane::orientationToTransfrom(
2679edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int orientation, int w, int h, Transform* tr)
2680eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian{
2681eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    uint32_t flags = 0;
2682edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (orientation) {
2683edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientationDefault:
2684eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_0;
2685eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        break;
2686edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientation90:
2687eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_90;
2688edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
2689edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientation180:
2690eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_180;
2691edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
2692edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientation270:
2693eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_270;
2694edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
2695edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    default:
2696edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return BAD_VALUE;
2697edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2698eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    tr->set(flags, w, h);
2699edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
2700edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2701edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2702edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t GraphicPlane::setOrientation(int orientation)
2703edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2704edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // If the rotation can be handled in hardware, this is where
2705edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // the magic should happen.
27062b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
27072b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const DisplayHardware& hw(displayHardware());
27082b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float w = mDisplayWidth;
27092b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float h = mDisplayHeight;
27102b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mWidth = int(w);
27112b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mHeight = int(h);
27122b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
27132b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    Transform orientationTransform;
2714eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    GraphicPlane::orientationToTransfrom(orientation, w, h,
2715eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian            &orientationTransform);
2716eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    if (orientation & ISurfaceComposer::eOrientationSwapMask) {
2717eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        mWidth = int(h);
2718eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        mHeight = int(w);
2719edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2720eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian
27210d1318b974feba2e6ff13e36a1781343c2fce045Mathias Agopian    mOrientation = orientation;
27222b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mGlobalTransform = mDisplayTransform * orientationTransform;
2723edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
2724edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2725edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2726edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst DisplayHardware& GraphicPlane::displayHardware() const {
2727edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return *mHw;
2728edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2729edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
273059119e658a12279e8fff508f8773843de2d90917Mathias AgopianDisplayHardware& GraphicPlane::editDisplayHardware() {
273159119e658a12279e8fff508f8773843de2d90917Mathias Agopian    return *mHw;
273259119e658a12279e8fff508f8773843de2d90917Mathias Agopian}
273359119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2734edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst Transform& GraphicPlane::transform() const {
2735edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return mGlobalTransform;
2736edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2737edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2738076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias AgopianEGLDisplay GraphicPlane::getEGLDisplay() const {
2739076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return mHw->getEGLDisplay();
2740076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
2741076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
2742edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
2743edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2744edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
2745