SurfaceFlinger.cpp revision 0dfb7b73a468698622d6c0423f0d5471a6f5d375
1edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/*
2edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
3edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
4edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * you may not use this file except in compliance with the License.
6edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * You may obtain a copy of the License at
7edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
8edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
10edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * See the License for the specific language governing permissions and
14edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * limitations under the License.
15edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */
16edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
17edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdlib.h>
18edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdio.h>
19edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdint.h>
20edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <unistd.h>
21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <fcntl.h>
22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <errno.h>
23edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <math.h>
24a837ba778f2d7a5170b37aa33624d9b9711c354dJean-Baptiste Queru#include <limits.h>
25edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/types.h>
26edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/stat.h>
27edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/ioctl.h>
28edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/log.h>
30edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/properties.h>
31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
32c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IPCThreadState.h>
33c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IServiceManager.h>
347303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian#include <binder/MemoryHeapBase.h>
3599b49840d309727678b77403d6cc9f920111623fMathias Agopian#include <binder/PermissionCache.h>
367303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
37edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String8.h>
38edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String16.h>
39edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/StopWatch.h>
40edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
413330b203039dea366d4981db1408a460134b2d2cMathias Agopian#include <ui/GraphicBufferAllocator.h>
4235b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian#include <ui/GraphicLog.h>
43edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/PixelFormat.h>
44edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <pixelflinger/pixelflinger.h>
46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <GLES/gl.h>
47edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
48edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h"
491f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian#include "GLExtensions.h"
508afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian#include "DdmConnection.h"
51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h"
52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerDim.h"
53118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian#include "LayerScreenshot.h"
54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h"
55edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "DisplayHardware/DisplayHardware.h"
57a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian#include "DisplayHardware/HWComposer.h"
58edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
59a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian#include <private/surfaceflinger/SharedBufferStack.h>
60a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
61a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian/* ideally AID_GRAPHICS would be in a semi-public header
62a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian * or there would be a way to map a user/group name to its id
63a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian */
64a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian#ifndef AID_GRAPHICS
65a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian#define AID_GRAPHICS 1003
66a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian#endif
67a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian
68edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DISPLAY_COUNT       1
69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
7399b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sHardwareTest("android.permission.HARDWARE_TEST");
7499b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER");
7599b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER");
7699b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sDump("android.permission.DUMP");
7799b49840d309727678b77403d6cc9f920111623fMathias Agopian
7899b49840d309727678b77403d6cc9f920111623fMathias Agopian// ---------------------------------------------------------------------------
7999b49840d309727678b77403d6cc9f920111623fMathias Agopian
80edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::SurfaceFlinger()
81edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    :   BnSurfaceComposer(), Thread(false),
82edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mTransactionFlags(0),
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
4493a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian    if (mDirtyRegion.isEmpty()) {
4503a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian        // nothing new to do.
4513a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian        return true;
4523a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian    }
4533a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian
454a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    if (UNLIKELY(mHwWorkListDirty)) {
455a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        // build the h/w work list
456a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        handleWorkList();
457a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
458a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
459edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw(graphicPlane(0).displayHardware());
460a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    if (LIKELY(hw.canDraw())) {
461edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // repaint the framebuffer (if needed)
46235b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian
46335b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        const int index = hw.getCurrentBufferIndex();
46435b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        GraphicLog& logger(GraphicLog::getInstance());
46535b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian
46635b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        logger.log(GraphicLog::SF_REPAINT, index);
467edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        handleRepaint();
468edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
46974faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian        // inform the h/w that we're done compositing
47035b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        logger.log(GraphicLog::SF_COMPOSITION_COMPLETE, index);
47174faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian        hw.compositionComplete();
47274faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian
47335b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        logger.log(GraphicLog::SF_SWAP_BUFFERS, index);
4748392b504bdf63ac7820c79c7217a89f2b2411bd0Antti Hatala        postFramebuffer();
4758392b504bdf63ac7820c79c7217a89f2b2411bd0Antti Hatala
47635b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        logger.log(GraphicLog::SF_REPAINT_DONE, index);
477edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
478edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // pretend we did the post
479e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian        hw.compositionComplete();
480edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        usleep(16667); // 60 fps period
481edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
482edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return true;
483edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
484edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
485edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer()
486edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
4873a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian    // this should never happen. we do the flip anyways so we don't
4883a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian    // risk to cause a deadlock with hwc
4893a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian    LOGW_IF(mSwapRegion.isEmpty(), "mSwapRegion is empty");
490a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
491a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    const nsecs_t now = systemTime();
492a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = now;
493a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    hw.flip(mSwapRegion);
494a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mLastSwapBufferTime = systemTime() - now;
495a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = 0;
496a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mSwapRegion.clear();
497edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
498edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
499edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleConsoleEvents()
500edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
501edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // something to do with the console
502edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw = graphicPlane(0).displayHardware();
503edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
504edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int what = android_atomic_and(0, &mConsoleSignals);
505edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (what & eConsoleAcquired) {
506edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        hw.acquireScreen();
5079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // this is a temporary work-around, eventually this should be called
5089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // by the power-manager
509abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        SurfaceFlinger::turnElectronBeamOn(mElectronBeamAnimationMode);
510edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
511edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
512edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (what & eConsoleReleased) {
51359119e658a12279e8fff508f8773843de2d90917Mathias Agopian        if (hw.isScreenAcquired()) {
514edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            hw.releaseScreen();
515edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
516edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
517edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
518edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDirtyRegion.set(hw.bounds());
519edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
520edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
521edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
522edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
523ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    Mutex::Autolock _l(mStateLock);
524ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    const nsecs_t now = systemTime();
525ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = now;
526ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
527ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // Here we're guaranteed that some transaction flags are set
528ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // so we can call handleTransactionLocked() unconditionally.
529ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // We call getTransactionFlags(), which will also clear the flags,
530ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // with mStateLock held to guarantee that mCurrentState won't change
531ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // until the transaction is committed.
532ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
533ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
534ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    transactionFlags = getTransactionFlags(mask);
535ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    handleTransactionLocked(transactionFlags);
536ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
537ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mLastTransactionTime = systemTime() - now;
538ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = 0;
539ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    invalidateHwcGeometry();
540ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // here the transaction has been committed
5413d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian}
542edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
543ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopianvoid SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
5443d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{
5453d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    const LayerVector& currentLayers(mCurrentState.layersSortedByZ);
546edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t count = currentLayers.size();
547edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
548edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
549edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Traversal of the children
550edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * (perform the transaction for each of them if needed)
551edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
552edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
553edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const bool layersNeedTransaction = transactionFlags & eTraversalNeeded;
554edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (layersNeedTransaction) {
555edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (size_t i=0 ; i<count ; i++) {
556076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            const sp<LayerBase>& layer = currentLayers[i];
557edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
558edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (!trFlags) continue;
559edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
560edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const uint32_t flags = layer->doTransaction(0);
561edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (flags & Layer::eVisibleRegion)
562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mVisibleRegionsDirty = true;
563edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
564edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
565edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
566edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
567edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Perform our own transaction if needed
568edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
569edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
570edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (transactionFlags & eTransactionNeeded) {
571edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (mCurrentState.orientation != mDrawingState.orientation) {
572edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // the orientation has changed, recompute all visible regions
573edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // and invalidate everything.
574edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
575edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int dpy = 0;
576edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int orientation = mCurrentState.orientation;
57721230c6410bdab13cd2bd274da54b1e4061b6035Jeff Brown            // Currently unused: const uint32_t flags = mCurrentState.orientationFlags;
578edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            GraphicPlane& plane(graphicPlane(dpy));
579edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            plane.setOrientation(orientation);
580edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
581edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // update the shared control block
582edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const DisplayHardware& hw(plane.displayHardware());
583edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            volatile display_cblk_t* dcblk = mServerCblk->displays + dpy;
584edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dcblk->orientation = orientation;
5852b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            dcblk->w = plane.getWidth();
5862b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            dcblk->h = plane.getHeight();
587edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
588edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
589edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mDirtyRegion.set(hw.bounds());
590edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
591edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
592edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (mCurrentState.freezeDisplay != mDrawingState.freezeDisplay) {
593edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // freezing or unfreezing the display -> trigger animation if needed
594edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mFreezeDisplay = mCurrentState.freezeDisplay;
595064e1e672e62094b32f8cf7a77a3b04c3309dc79Mathias Agopian            if (mFreezeDisplay)
596064e1e672e62094b32f8cf7a77a3b04c3309dc79Mathias Agopian                 mFreezeDisplayTime = 0;
597edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
598edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5990aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        if (currentLayers.size() > mDrawingState.layersSortedByZ.size()) {
6000aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            // layers have been added
601edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
602edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
603edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
6040aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        // some layers might have been removed, so
6050aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        // we need to update the regions they're exposing.
6060aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        if (mLayersRemoved) {
60748d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian            mLayersRemoved = false;
608edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
6090aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            const LayerVector& previousLayers(mDrawingState.layersSortedByZ);
6103d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian            const size_t count = previousLayers.size();
6113d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian            for (size_t i=0 ; i<count ; i++) {
6120aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                const sp<LayerBase>& layer(previousLayers[i]);
6130aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                if (currentLayers.indexOf( layer ) < 0) {
6140aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                    // this layer is not visible anymore
6155d7126b625c8c4a7b945e8c247b63abff7bc13b6Mathias Agopian                    mDirtyRegionRemovedLayer.orSelf(layer->visibleRegionScreen);
6160aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                }
6170aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            }
618edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
619edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
620edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
621edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    commitTransaction();
622edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
623edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
624edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectsp<FreezeLock> SurfaceFlinger::getFreezeLock() const
625edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
626edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return new FreezeLock(const_cast<SurfaceFlinger *>(this));
627edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
628edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
629edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::computeVisibleRegions(
6301bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian    const LayerVector& currentLayers, Region& dirtyRegion, Region& opaqueRegion)
631edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
632edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(graphicPlane(0));
633edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Transform& planeTransform(plane.transform());
634ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian    const DisplayHardware& hw(plane.displayHardware());
635ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian    const Region screenRegion(hw.bounds());
636edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
637edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveOpaqueLayers;
638edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveCoveredLayers;
639edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region dirty;
640edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
641edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    bool secureFrameBuffer = false;
642edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
643edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t i = currentLayers.size();
644edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    while (i--) {
645076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        const sp<LayerBase>& layer = currentLayers[i];
646edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->validateVisibility(planeTransform);
647edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
648edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // start with the whole surface at its current location
649970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian        const Layer::State& s(layer->drawingState());
650edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
651ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
652ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * opaqueRegion: area of a surface that is fully opaque.
653ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
654edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region opaqueRegion;
655ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
656ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
657ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visibleRegion: area of a surface that is visible on screen
658ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * and not fully transparent. This is essentially the layer's
659ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * footprint minus the opaque regions above it.
660ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * Areas covered by a translucent surface are considered visible.
661ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
662edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region visibleRegion;
663ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
664ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
665ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * coveredRegion: area of a surface that is covered by all
666ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visible regions above it (which includes the translucent areas).
667ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
668edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region coveredRegion;
669ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
670ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
671ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // handle hidden surfaces by setting the visible region to empty
672970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian        if (LIKELY(!(s.flags & ISurfaceComposer::eLayerHidden) && s.alpha)) {
673a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            const bool translucent = !layer->isOpaque();
674970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian            const Rect bounds(layer->visibleBounds());
675edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            visibleRegion.set(bounds);
676ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            visibleRegion.andSelf(screenRegion);
677ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            if (!visibleRegion.isEmpty()) {
678ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // Remove the transparent area from the visible region
679ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (translucent) {
680ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    visibleRegion.subtractSelf(layer->transparentRegionScreen);
681ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
682edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
683ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // compute the opaque region
684ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                const int32_t layerOrientation = layer->getOrientation();
685ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (s.alpha==255 && !translucent &&
686ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                        ((layerOrientation & Transform::ROT_INVALID) == false)) {
687ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    // the opaque region is the layer's footprint
688ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    opaqueRegion = visibleRegion;
689ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
690edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
691edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
692edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
693ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Clip the covered region to the visible region
694ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        coveredRegion = aboveCoveredLayers.intersect(visibleRegion);
695ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
696ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveCoveredLayers for next (lower) layer
697ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        aboveCoveredLayers.orSelf(visibleRegion);
698ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
699edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // subtract the opaque region covered by the layers above us
700edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        visibleRegion.subtractSelf(aboveOpaqueLayers);
701edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
702edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // compute this layer's dirty region
703edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (layer->contentDirty) {
704edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // we need to invalidate the whole region
705edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dirty = visibleRegion;
706edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // as well, as the old visible region
707edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dirty.orSelf(layer->visibleRegionScreen);
708edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->contentDirty = false;
709edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
710a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian            /* compute the exposed region:
711ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   the exposed region consists of two components:
712ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   1) what's VISIBLE now and was COVERED before
713ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   2) what's EXPOSED now less what was EXPOSED before
714ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
715ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * note that (1) is conservative, we start with the whole
716ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * visible region but only keep what used to be covered by
717ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * something -- which mean it may have been exposed.
718ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
719ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * (2) handles areas that were not covered by anything but got
720ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * exposed because of a resize.
721a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian             */
722ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region newExposed = visibleRegion - coveredRegion;
723ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldVisibleRegion = layer->visibleRegionScreen;
724ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldCoveredRegion = layer->coveredRegionScreen;
725ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldExposed = oldVisibleRegion - oldCoveredRegion;
726ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed);
727edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
728edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirty.subtractSelf(aboveOpaqueLayers);
729edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
730edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // accumulate to the screen dirty region
731edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirtyRegion.orSelf(dirty);
732edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
733ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveOpaqueLayers for next (lower) layer
734edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        aboveOpaqueLayers.orSelf(opaqueRegion);
7358b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
736edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // Store the visible region is screen space
737edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setVisibleRegion(visibleRegion);
738edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setCoveredRegion(coveredRegion);
739edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
740970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian        // If a secure layer is partially visible, lock-down the screen!
741edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (layer->isSecure() && !visibleRegion.isEmpty()) {
742edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            secureFrameBuffer = true;
743edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
744edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
745edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
746970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian    // invalidate the areas where a layer was removed
747970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian    dirtyRegion.orSelf(mDirtyRegionRemovedLayer);
748970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian    mDirtyRegionRemovedLayer.clear();
749970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian
750edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mSecureFrameBuffer = secureFrameBuffer;
751edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    opaqueRegion = aboveOpaqueLayers;
752edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
753edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
754edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
755edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::commitTransaction()
756edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
757edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDrawingState = mCurrentState;
758cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mResizeTransationPending = false;
759cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mTransactionCV.broadcast();
760edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
761edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
762edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handlePageFlip()
763edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
764edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    bool visibleRegions = mVisibleRegionsDirty;
7651bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian    const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
766edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    visibleRegions |= lockPageFlip(currentLayers);
767edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
768edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const DisplayHardware& hw = graphicPlane(0).displayHardware();
769edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const Region screenRegion(hw.bounds());
770edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (visibleRegions) {
771edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            Region opaqueRegion;
772edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            computeVisibleRegions(currentLayers, mDirtyRegion, opaqueRegion);
7734da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
7744da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            /*
7754da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian             *  rebuild the visible layer list
7764da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian             */
7771bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian            const size_t count = currentLayers.size();
7784da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            mVisibleLayersSortedByZ.clear();
7794da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            mVisibleLayersSortedByZ.setCapacity(count);
7804da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            for (size_t i=0 ; i<count ; i++) {
7814da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian                if (!currentLayers[i]->visibleRegionScreen.isEmpty())
7824da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian                    mVisibleLayersSortedByZ.add(currentLayers[i]);
7834da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            }
7844da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
785edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mWormholeRegion = screenRegion.subtract(opaqueRegion);
786edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = false;
787ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian            invalidateHwcGeometry();
788edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
789edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
790edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    unlockPageFlip(currentLayers);
7910dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian
7920dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    mDirtyRegion.orSelf(getAndClearInvalidateRegion());
793edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDirtyRegion.andSelf(screenRegion);
794edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
795edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
796ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopianvoid SurfaceFlinger::invalidateHwcGeometry()
797ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian{
798ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian    mHwWorkListDirty = true;
799ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian}
800ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian
801edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool SurfaceFlinger::lockPageFlip(const LayerVector& currentLayers)
802edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
803edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    bool recomputeVisibleRegions = false;
804edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t count = currentLayers.size();
805076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBase> const* layers = currentLayers.array();
806edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (size_t i=0 ; i<count ; i++) {
807b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
808edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->lockPageFlip(recomputeVisibleRegions);
809edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
810edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return recomputeVisibleRegions;
811edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
812edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
813edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::unlockPageFlip(const LayerVector& currentLayers)
814edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
815edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(graphicPlane(0));
816edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Transform& planeTransform(plane.transform());
817edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t count = currentLayers.size();
818076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBase> const* layers = currentLayers.array();
819edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (size_t i=0 ; i<count ; i++) {
820b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
821edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->unlockPageFlip(planeTransform, mDirtyRegion);
822edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
823edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
824edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
825a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopianvoid SurfaceFlinger::handleWorkList()
826a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian{
827a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    mHwWorkListDirty = false;
828a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    HWComposer& hwc(graphicPlane(0).displayHardware().getHwComposer());
829a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    if (hwc.initCheck() == NO_ERROR) {
830a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        const Vector< sp<LayerBase> >& currentLayers(mVisibleLayersSortedByZ);
831a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        const size_t count = currentLayers.size();
832a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        hwc.createWorkList(count);
83345721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        hwc_layer_t* const cur(hwc.getLayers());
83445721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        for (size_t i=0 ; cur && i<count ; i++) {
83545721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            currentLayers[i]->setGeometry(&cur[i]);
83653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian            if (mDebugDisableHWC || mDebugRegion) {
83773d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian                cur[i].compositionType = HWC_FRAMEBUFFER;
83873d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian                cur[i].flags |= HWC_SKIP_LAYER;
83973d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian            }
840a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        }
841a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
842a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian}
843b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian
844edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleRepaint()
845edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
846b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // compute the invalid region
8470656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian    mSwapRegion.orSelf(mDirtyRegion);
848edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
849edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(mDebugRegion)) {
850edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        debugFlashRegions();
851edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
852edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
853b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // set the frame buffer
854b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
855b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    glMatrixMode(GL_MODELVIEW);
856b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    glLoadIdentity();
857edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
858edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t flags = hw.getFlags();
8598b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber    if ((flags & DisplayHardware::SWAP_RECTANGLE) ||
8608b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber        (flags & DisplayHardware::BUFFER_PRESERVED))
861df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian    {
86229d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // we can redraw only what's dirty, but since SWAP_RECTANGLE only
86329d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // takes a rectangle, we must make sure to update that whole
86429d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // rectangle in that case
86529d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        if (flags & DisplayHardware::SWAP_RECTANGLE) {
866b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            // TODO: we really should be able to pass a region to
86729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // SWAP_RECTANGLE so that we don't have to redraw all this.
8680656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian            mDirtyRegion.set(mSwapRegion.bounds());
86929d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        } else {
87029d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // in the BUFFER_PRESERVED case, obviously, we can update only
87129d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // what's needed and nothing more.
87229d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // NOTE: this is NOT a common case, as preserving the backbuffer
87329d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // is costly and usually involves copying the whole update back.
87429d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        }
875edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
87695a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian        if (flags & DisplayHardware::PARTIAL_UPDATES) {
87729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // We need to redraw the rectangle that will be updated
878df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian            // (pushed to the framebuffer).
87995a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian            // This is needed because PARTIAL_UPDATES only takes one
88029d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // rectangle instead of a region (see DisplayHardware::flip())
8810656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian            mDirtyRegion.set(mSwapRegion.bounds());
882edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
88329d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // we need to redraw everything (the whole screen)
884edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mDirtyRegion.set(hw.bounds());
8850656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian            mSwapRegion = mDirtyRegion;
886edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
887edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
888edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
8899c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    setupHardwareComposer(mDirtyRegion);
890edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    composeSurfaces(mDirtyRegion);
891edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
8929c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    // update the swap region and clear the dirty region
8939c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    mSwapRegion.orSelf(mDirtyRegion);
894edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDirtyRegion.clear();
895edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
896edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
8979c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopianvoid SurfaceFlinger::setupHardwareComposer(Region& dirtyInOut)
898edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
899f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
900f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    HWComposer& hwc(hw.getHwComposer());
901f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    hwc_layer_t* const cur(hwc.getLayers());
902f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    if (!cur) {
9039c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        return;
904edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
905a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
9064da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian    const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
90745721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    size_t count = layers.size();
908a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
909f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    LOGE_IF(hwc.getNumLayers() != count,
91045721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            "HAL number of layers (%d) doesn't match surfaceflinger (%d)",
91145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            hwc.getNumLayers(), count);
912a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
91345721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    // just to be extra-safe, use the smallest count
91424925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling    if (hwc.initCheck() == NO_ERROR) {
91524925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling        count = count < hwc.getNumLayers() ? count : hwc.getNumLayers();
91624925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling    }
917a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
91845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    /*
91945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     *  update the per-frame h/w composer data for each layer
92045721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     *  and build the transparent region of the FB
92145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     */
922f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
923f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
924f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        layer->setPerFrameData(&cur[i]);
925f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    }
9269c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    const size_t fbLayerCount = hwc.getLayerCount(HWC_FRAMEBUFFER);
927f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    status_t err = hwc.prepare();
928f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    LOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
929f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian
930f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    if (err == NO_ERROR) {
9319c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // what's happening here is tricky.
9329c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // we want to clear all the layers with the CLEAR_FB flags
9339c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // that are opaque.
9349c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // however, since some GPU are efficient at preserving
9359c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // the backbuffer, we want to take advantage of that so we do the
9369c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // clear only in the dirty region (other areas will be preserved
9379c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // on those GPUs).
9389c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        //   NOTE: on non backbuffer preserving GPU, the dirty region
9399c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        //   has already been expanded as needed, so the code is correct
9409c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        //   there too.
9419c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        //
9429c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // However, the content of the framebuffer cannot be trusted when
9439c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // we switch to/from FB/OVERLAY, in which case we need to
9449c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // expand the dirty region to those areas too.
9459c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        //
9469c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // Note also that there is a special case when switching from
9479c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // "no layers in FB" to "some layers in FB", where we need to redraw
9489c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // the entire FB, since some areas might contain uninitialized
9499c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // data.
9509c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        //
9519c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // Also we want to make sure to not clear areas that belong to
9523a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian        // layers above that won't redraw (we would just be erasing them),
9539c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // that is, we can't erase anything outside the dirty region.
954a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
9559c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        Region transparent;
956f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian
9579c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        if (!fbLayerCount && hwc.getLayerCount(HWC_FRAMEBUFFER)) {
9589c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian            transparent.set(hw.getBounds());
9599c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian            dirtyInOut = transparent;
9609c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        } else {
9619c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian            for (size_t i=0 ; i<count ; i++) {
9629c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                const sp<LayerBase>& layer(layers[i]);
9639c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                if ((cur[i].hints & HWC_HINT_CLEAR_FB) && layer->isOpaque()) {
9649c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                    transparent.orSelf(layer->visibleRegionScreen);
9659c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                }
9669c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                bool isOverlay = (cur[i].compositionType != HWC_FRAMEBUFFER);
9679c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                if (isOverlay != layer->isOverlay()) {
9689c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                    // we transitioned to/from overlay, so add this layer
9699c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                    // to the dirty region so the framebuffer can be either
9709c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                    // cleared or redrawn.
9719c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                    dirtyInOut.orSelf(layer->visibleRegionScreen);
9729c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                }
9739c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                layer->setOverlay(isOverlay);
974f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian            }
9759c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian            // don't erase stuff outside the dirty region
9769c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian            transparent.andSelf(dirtyInOut);
977f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        }
978f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian
979f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        /*
980f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian         *  clear the area of the FB that need to be transparent
981f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian         */
982f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        if (!transparent.isEmpty()) {
983f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian            glClearColor(0,0,0,0);
984f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian            Region::const_iterator it = transparent.begin();
985f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian            Region::const_iterator const end = transparent.end();
986f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian            const int32_t height = hw.getHeight();
987f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian            while (it != end) {
988f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian                const Rect& r(*it++);
989f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian                const GLint sy = height - (r.top + r.height());
990f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian                glScissor(r.left, sy, r.width(), r.height());
991f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian                glClear(GL_COLOR_BUFFER_BIT);
992f20a32415d055336bc6016fa2de36d126db32746Mathias Agopian            }
993a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        }
994a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
995f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian}
996f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian
997f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopianvoid SurfaceFlinger::composeSurfaces(const Region& dirty)
998f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian{
999cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
1000cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian    HWComposer& hwc(hw.getHwComposer());
1001cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian
1002cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian    const size_t fbLayerCount = hwc.getLayerCount(HWC_FRAMEBUFFER);
1003cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian    if (UNLIKELY(fbLayerCount && !mWormholeRegion.isEmpty())) {
1004f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        // should never happen unless the window manager has a bug
1005f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        // draw something...
1006f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        drawWormhole();
1007f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    }
100845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian
100945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    /*
101045721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     * and then, render the layers targeted at the framebuffer
101145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     */
1012cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian    hwc_layer_t* const cur(hwc.getLayers());
1013f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
1014f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    size_t count = layers.size();
101545721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
10169c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        if (cur && (cur[i].compositionType != HWC_FRAMEBUFFER)) {
1017f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian            continue;
101845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        }
101945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
102045721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        const Region clip(dirty.intersect(layer->visibleRegionScreen));
102145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        if (!clip.isEmpty()) {
102245721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            layer->draw(clip);
102345721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        }
102445721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    }
1025edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1026edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1027edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::debugFlashRegions()
1028edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
10290a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
10300a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    const uint32_t flags = hw.getFlags();
103153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian    const int32_t height = hw.getHeight();
10320656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian    if (mSwapRegion.isEmpty()) {
103353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian        return;
103453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian    }
10350a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
10360a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    if (!((flags & DisplayHardware::SWAP_RECTANGLE) ||
10370a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian            (flags & DisplayHardware::BUFFER_PRESERVED))) {
10380a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        const Region repaint((flags & DisplayHardware::PARTIAL_UPDATES) ?
10390a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian                mDirtyRegion.bounds() : hw.bounds());
10400a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        composeSurfaces(repaint);
10410a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    }
10420a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
1043c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_EXTERNAL_OES);
1044c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_2D);
1045edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_BLEND);
1046edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_SCISSOR_TEST);
1047edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
10480926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    static int toggle = 0;
10490926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    toggle = 1 - toggle;
10500926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    if (toggle) {
10510a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        glColor4f(1, 0, 1, 1);
10520926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    } else {
10530a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        glColor4f(1, 1, 0, 1);
10540926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    }
1055edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
105620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    Region::const_iterator it = mDirtyRegion.begin();
105720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    Region::const_iterator const end = mDirtyRegion.end();
105820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    while (it != end) {
105920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        const Rect& r = *it++;
1060edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLfloat vertices[][2] = {
106153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.left,  height - r.top },
106253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.left,  height - r.bottom },
106353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.right, height - r.bottom },
106453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.right, height - r.top }
1065edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        };
1066edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glVertexPointer(2, GL_FLOAT, 0, vertices);
1067edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1068edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
10690a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
10700656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian    hw.flip(mSwapRegion);
1071edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1072edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mDebugRegion > 1)
10730a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        usleep(mDebugRegion * 1000);
1074edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1075edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glEnable(GL_SCISSOR_TEST);
1076edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1077edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1078edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::drawWormhole() const
1079edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1080edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Region region(mWormholeRegion.intersect(mDirtyRegion));
1081edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (region.isEmpty())
1082edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1083edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1084edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw(graphicPlane(0).displayHardware());
1085edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int32_t width = hw.getWidth();
1086edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int32_t height = hw.getHeight();
1087edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1088edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (LIKELY(!mDebugBackground)) {
10890a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        glClearColor(0,0,0,0);
109020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        Region::const_iterator it = region.begin();
109120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        Region::const_iterator const end = region.end();
109220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        while (it != end) {
109320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            const Rect& r = *it++;
1094edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const GLint sy = height - (r.top + r.height());
1095edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glScissor(r.left, sy, r.width(), r.height());
1096edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glClear(GL_COLOR_BUFFER_BIT);
1097edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1098edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
1099edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GLshort vertices[][2] = { { 0, 0 }, { width, 0 },
1100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                { width, height }, { 0, height }  };
1101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GLshort tcoords[][2] = { { 0, 0 }, { 1, 0 },  { 1, 1 }, { 0, 1 } };
1102c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian
1103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glVertexPointer(2, GL_SHORT, 0, vertices);
1104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glTexCoordPointer(2, GL_SHORT, 0, tcoords);
1105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
1106c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian
1107c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian        glDisable(GL_TEXTURE_EXTERNAL_OES);
1108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glEnable(GL_TEXTURE_2D);
1109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glBindTexture(GL_TEXTURE_2D, mWormholeTexName);
1110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glMatrixMode(GL_TEXTURE);
1112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glLoadIdentity();
1113c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian
1114c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian        glDisable(GL_BLEND);
1115c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian
1116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glScalef(width*(1.0f/32.0f), height*(1.0f/32.0f), 1);
111720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        Region::const_iterator it = region.begin();
111820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        Region::const_iterator const end = region.end();
111920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        while (it != end) {
112020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            const Rect& r = *it++;
1121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const GLint sy = height - (r.top + r.height());
1122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glScissor(r.left, sy, r.width(), r.height());
1123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1125edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1126a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        glDisable(GL_TEXTURE_2D);
1127ebeb7095961e09f5cff0c7cf2c04fa4770b2e033Mathias Agopian        glLoadIdentity();
1128ebeb7095961e09f5cff0c7cf2c04fa4770b2e033Mathias Agopian        glMatrixMode(GL_MODELVIEW);
1129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::debugShowFPS() const
1133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    static int mFrameCount;
1135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    static int mLastFrameCount = 0;
1136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    static nsecs_t mLastFpsTime = 0;
1137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    static float mFps = 0;
1138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mFrameCount++;
1139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    nsecs_t now = systemTime();
1140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    nsecs_t diff = now - mLastFpsTime;
1141edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (diff > ms2ns(250)) {
1142edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mFps =  ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff;
1143edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mLastFpsTime = now;
1144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mLastFrameCount = mFrameCount;
1145edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1146edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // XXX: mFPS has the value we want
1147edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project }
1148edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1149076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::addLayer(const sp<LayerBase>& layer)
1150edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1151edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
1152edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    addLayer_l(layer);
1153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
1154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1157076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::addLayer_l(const sp<LayerBase>& layer)
1158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1159f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian    ssize_t i = mCurrentState.layersSortedByZ.add(layer);
11601b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    return (i < 0) ? status_t(i) : status_t(NO_ERROR);
11611b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian}
11621b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
116396f0819f81293076e652792794a961543e6750d7Mathias Agopianssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
116496f0819f81293076e652792794a961543e6750d7Mathias Agopian        const sp<LayerBaseClient>& lbc)
11651b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
116696f0819f81293076e652792794a961543e6750d7Mathias Agopian    // attach this layer to the client
11674f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    size_t name = client->attachLayer(lbc);
11684f113740180b6512b43723c4728f262882dc9b45Mathias Agopian
11694f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    Mutex::Autolock _l(mStateLock);
117096f0819f81293076e652792794a961543e6750d7Mathias Agopian
117196f0819f81293076e652792794a961543e6750d7Mathias Agopian    // add this layer to the current state list
117296f0819f81293076e652792794a961543e6750d7Mathias Agopian    addLayer_l(lbc);
117396f0819f81293076e652792794a961543e6750d7Mathias Agopian
11744f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    return ssize_t(name);
117596f0819f81293076e652792794a961543e6750d7Mathias Agopian}
117696f0819f81293076e652792794a961543e6750d7Mathias Agopian
117796f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer)
117896f0819f81293076e652792794a961543e6750d7Mathias Agopian{
117996f0819f81293076e652792794a961543e6750d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
118096f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = purgatorizeLayer_l(layer);
118196f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR)
118296f0819f81293076e652792794a961543e6750d7Mathias Agopian        setTransactionFlags(eTransactionNeeded);
118396f0819f81293076e652792794a961543e6750d7Mathias Agopian    return err;
1184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1186076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase)
1187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1188b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<LayerBaseClient> lbc(layerBase->getLayerBaseClient());
1189b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (lbc != 0) {
11900d1561275e80073807ac04728951782d943f8882Mathias Agopian        mLayerMap.removeItem( lbc->getSurfaceBinder() );
1191b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    }
1192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase);
1193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (index >= 0) {
1194076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved = true;
1195edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
1196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
11973d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    return status_t(index);
1198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1199edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
12009a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase)
12019a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
120276cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    // First add the layer to the purgatory list, which makes sure it won't
120376cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    // go away, then remove it from the main list (through a transaction).
12049a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    ssize_t err = removeLayer_l(layerBase);
120576cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    if (err >= 0) {
120676cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian        mLayerPurgatory.add(layerBase);
120776cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    }
12088c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian
12090b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian    layerBase->onRemoved();
12100b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian
12113d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // it's possible that we don't find a layer, because it might
12123d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // have been destroyed already -- this is not technically an error
121396f0819f81293076e652792794a961543e6750d7Mathias Agopian    // from the user because there is a race between Client::destroySurface(),
121496f0819f81293076e652792794a961543e6750d7Mathias Agopian    // ~Client() and ~ISurface().
12159a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err;
12169a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
12179a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
121896f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::invalidateLayerVisibility(const sp<LayerBase>& layer)
1219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
122096f0819f81293076e652792794a961543e6750d7Mathias Agopian    layer->forceVisibilityTransaction();
122196f0819f81293076e652792794a961543e6750d7Mathias Agopian    setTransactionFlags(eTraversalNeeded);
122296f0819f81293076e652792794a961543e6750d7Mathias Agopian    return NO_ERROR;
1223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1225dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopianuint32_t SurfaceFlinger::peekTransactionFlags(uint32_t flags)
1226dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian{
1227dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian    return android_atomic_release_load(&mTransactionFlags);
1228dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian}
1229dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian
1230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags)
1231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return android_atomic_and(~flags, &mTransactionFlags) & flags;
1233edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1235bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags)
1236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t old = android_atomic_or(flags, &mTransactionFlags);
1238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((old & flags)==0) { // wake the server up
1239bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        signalEvent();
1240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return old;
1242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1245b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennisvoid SurfaceFlinger::setTransactionState(const Vector<ComposerState>& state,
1246b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis        int orientation) {
1247698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
1248cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
1249698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    uint32_t flags = 0;
1250b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis    if (mCurrentState.orientation != orientation) {
1251b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis        if (uint32_t(orientation)<=eOrientation270 || orientation==42) {
1252b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis            mCurrentState.orientation = orientation;
1253b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis            flags |= eTransactionNeeded;
1254b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis            mResizeTransationPending = true;
1255b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis        } else if (orientation != eOrientationUnchanged) {
1256b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis            LOGW("setTransactionState: ignoring unrecognized orientation: %d",
1257b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis                    orientation);
1258b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis        }
1259b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis    }
1260b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis
1261698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    const size_t count = state.size();
1262698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
1263698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const ComposerState& s(state[i]);
1264698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        sp<Client> client( static_cast<Client *>(s.client.get()) );
1265698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        flags |= setClientStateLocked(client, s.state);
1266698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    }
1267698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    if (flags) {
1268698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        setTransactionFlags(flags);
1269698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    }
1270698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian
1271698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    signalEvent();
1272698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian
1273698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    // if there is a transaction with a resize, wait for it to
1274698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    // take effect before returning.
1275698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    while (mResizeTransationPending) {
1276698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
1277698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (CC_UNLIKELY(err != NO_ERROR)) {
1278698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            // just in case something goes wrong in SF, return to the
1279698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            // called after a few seconds.
1280698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            LOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!");
1281698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            mResizeTransationPending = false;
1282698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            break;
1283cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        }
1284edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1285edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1286edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1287edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::freezeDisplay(DisplayID dpy, uint32_t flags)
1288edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1289edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
1290edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return BAD_VALUE;
1291edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1292edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
1293edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mCurrentState.freezeDisplay = 1;
1294edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    setTransactionFlags(eTransactionNeeded);
1295edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // flags is intended to communicate some sort of animation behavior
129762b74444be6742ab6b877918c85caeb9f2f1a2c9Mathias Agopian    // (for instance fading)
1298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1301edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::unfreezeDisplay(DisplayID dpy, uint32_t flags)
1302edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
1304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return BAD_VALUE;
1305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
1307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mCurrentState.freezeDisplay = 0;
1308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    setTransactionFlags(eTransactionNeeded);
1309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1310edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // flags is intended to communicate some sort of animation behavior
131162b74444be6742ab6b877918c85caeb9f2f1a2c9Mathias Agopian    // (for instance fading)
1312edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1313edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1314edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
13158b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huberint SurfaceFlinger::setOrientation(DisplayID dpy,
1316c08731e756868653d09d3e49b723706df3687070Mathias Agopian        int orientation, uint32_t flags)
1317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
1319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return BAD_VALUE;
1320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
1322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mCurrentState.orientation != orientation) {
1323edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (uint32_t(orientation)<=eOrientation270 || orientation==42) {
132421230c6410bdab13cd2bd274da54b1e4061b6035Jeff Brown            mCurrentState.orientationFlags = flags;
1325edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mCurrentState.orientation = orientation;
1326edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            setTransactionFlags(eTransactionNeeded);
1327edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mTransactionCV.wait(mStateLock);
1328edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
1329edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            orientation = BAD_VALUE;
1330edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1331edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1332edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return orientation;
1333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1334edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
13350ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopiansp<ISurface> SurfaceFlinger::createSurface(
13360ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        ISurfaceComposerClient::surface_data_t* params,
13370ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const String8& name,
13380ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const sp<Client>& client,
1339edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        DisplayID d, uint32_t w, uint32_t h, PixelFormat format,
1340edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t flags)
1341edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1342076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBaseClient> layer;
1343a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    sp<ISurface> surfaceHandle;
13446e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian
13456e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    if (int32_t(w|h) < 0) {
13466e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian        LOGE("createSurface() failed, w or h is negative (w=%d, h=%d)",
13476e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian                int(w), int(h));
13486e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian        return surfaceHandle;
13496e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    }
13508b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
1351edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    //LOGD("createSurface for pid %d (%d x %d)", pid, w, h);
1352b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<Layer> normalLayer;
1353edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (flags & eFXSurfaceMask) {
1354edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceNormal:
1355a5529c8778c2f407f482fc12165aeb76c0f505c2Mathias Agopian            normalLayer = createNormalSurface(client, d, w, h, flags, format);
1356a5529c8778c2f407f482fc12165aeb76c0f505c2Mathias Agopian            layer = normalLayer;
1357edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
1358edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceBlur:
13591293a8eb567fd63c072a6970fa9dcf37d076059fMathias Agopian            // for now we treat Blur as Dim, until we can implement it
13601293a8eb567fd63c072a6970fa9dcf37d076059fMathias Agopian            // efficiently.
1361edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceDim:
136296f0819f81293076e652792794a961543e6750d7Mathias Agopian            layer = createDimSurface(client, d, w, h, flags);
1363edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
1364118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        case eFXSurfaceScreenshot:
1365118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian            layer = createScreenshotSurface(client, d, w, h, flags);
1366118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian            break;
1367edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1368edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1369076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (layer != 0) {
137096f0819f81293076e652792794a961543e6750d7Mathias Agopian        layer->initStates(w, h, flags);
1371285dbde2e0cd0057be070ded3be8f5f453147edcMathias Agopian        layer->setName(name);
137296f0819f81293076e652792794a961543e6750d7Mathias Agopian        ssize_t token = addClientLayer(client, layer);
1373b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1374edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        surfaceHandle = layer->getSurface();
13758b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber        if (surfaceHandle != 0) {
137696f0819f81293076e652792794a961543e6750d7Mathias Agopian            params->token = token;
1377a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            params->identity = layer->getIdentity();
1378b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            if (normalLayer != 0) {
1379b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian                Mutex::Autolock _l(mStateLock);
1380a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                mLayerMap.add(layer->getSurfaceBinder(), normalLayer);
1381b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            }
13821c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        }
1383b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
138496f0819f81293076e652792794a961543e6750d7Mathias Agopian        setTransactionFlags(eTransactionNeeded);
1385edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1386edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1387edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return surfaceHandle;
1388edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1389edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1390b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<Layer> SurfaceFlinger::createNormalSurface(
1391f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        const sp<Client>& client, DisplayID display,
139296f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags,
13931c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        PixelFormat& format)
1394edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1395edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize the surfaces
1396edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (format) { // TODO: take h/w into account
1397edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSPARENT:
1398edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSLUCENT:
1399edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        format = PIXEL_FORMAT_RGBA_8888;
1400edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1401edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_OPAQUE:
1402a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888
1403a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian        format = PIXEL_FORMAT_RGB_565;
1404a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#else
14058f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian        format = PIXEL_FORMAT_RGBX_8888;
1406a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif
1407edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1408edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1409edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1410a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888
1411a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian    if (format == PIXEL_FORMAT_RGBX_8888)
1412a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian        format = PIXEL_FORMAT_RGBA_8888;
1413a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif
1414a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian
141596f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<Layer> layer = new Layer(this, display, client);
1416f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian    status_t err = layer->setBuffers(w, h, format, flags);
141796f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (LIKELY(err != NO_ERROR)) {
1418edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        LOGE("createNormalSurfaceLocked() failed (%s)", strerror(-err));
1419076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        layer.clear();
1420edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1421edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1422edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1423edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1424b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<LayerDim> SurfaceFlinger::createDimSurface(
1425f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        const sp<Client>& client, DisplayID display,
142696f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags)
1427edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
142896f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<LayerDim> layer = new LayerDim(this, display, client);
1429118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    return layer;
1430118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
1431118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
1432118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopiansp<LayerScreenshot> SurfaceFlinger::createScreenshotSurface(
1433118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        const sp<Client>& client, DisplayID display,
1434118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags)
1435118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{
1436118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    sp<LayerScreenshot> layer = new LayerScreenshot(this, display, client);
1437118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    status_t err = layer->capture();
1438118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    if (err != NO_ERROR) {
1439118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        layer.clear();
1440118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        LOGW("createScreenshotSurface failed (%s)", strerror(-err));
1441118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    }
1442edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1443edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1444edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
144596f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeSurface(const sp<Client>& client, SurfaceID sid)
14469a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
14479a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    /*
14489a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     * called by the window manager, when a surface should be marked for
14499a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     * destruction.
14508b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber     *
14510aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * The surface is removed from the current and drawing lists, but placed
14520aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * in the purgatory queue, so it's not destroyed right-away (we need
14530aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * to wait for all client's references to go away first).
14549a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     */
14559a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
145648d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    status_t err = NAME_NOT_FOUND;
14570aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian    Mutex::Autolock _l(mStateLock);
145896f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<LayerBaseClient> layer = client->getLayerUser(sid);
145948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    if (layer != 0) {
146048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        err = purgatorizeLayer_l(layer);
146148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        if (err == NO_ERROR) {
146248d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian            setTransactionFlags(eTransactionNeeded);
146348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        }
14649a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    }
14659a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return err;
14669a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
14679a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
1468ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopianstatus_t SurfaceFlinger::destroySurface(const wp<LayerBaseClient>& layer)
1469edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1470759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian    // called by ~ISurface() when all references are gone
1471ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    status_t err = NO_ERROR;
1472ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    sp<LayerBaseClient> l(layer.promote());
1473ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    if (l != NULL) {
1474ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        Mutex::Autolock _l(mStateLock);
1475ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        err = removeLayer_l(l);
1476ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        if (err == NAME_NOT_FOUND) {
1477ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // The surface wasn't in the current list, which means it was
1478ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // removed already, which means it is in the purgatory,
1479ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // and need to be removed from there.
1480ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            ssize_t idx = mLayerPurgatory.remove(l);
1481ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            LOGE_IF(idx < 0,
1482ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian                    "layer=%p is not in the purgatory list", l.get());
1483f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        }
1484ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        LOGE_IF(err<0 && err != NAME_NOT_FOUND,
1485ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian                "error removing layer=%p (%s)", l.get(), strerror(-err));
1486ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    }
1487ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    return err;
1488edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1489edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1490698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopianuint32_t SurfaceFlinger::setClientStateLocked(
149196f0819f81293076e652792794a961543e6750d7Mathias Agopian        const sp<Client>& client,
1492698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const layer_state_t& s)
1493edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1494edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t flags = 0;
1495698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    sp<LayerBaseClient> layer(client->getLayerUser(s.surface));
1496698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    if (layer != 0) {
1497698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const uint32_t what = s.what;
1498698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & ePositionChanged) {
1499698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setPosition(s.x, s.y))
1500698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1501698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1502698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eLayerChanged) {
1503698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
1504698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setLayer(s.z)) {
1505698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                mCurrentState.layersSortedByZ.removeAt(idx);
1506698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                mCurrentState.layersSortedByZ.add(layer);
1507698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                // we need traversal (state changed)
1508698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                // AND transaction (list changed)
1509698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTransactionNeeded|eTraversalNeeded;
1510edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1511698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1512698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eSizeChanged) {
1513698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setSize(s.w, s.h)) {
1514698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1515698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                mResizeTransationPending = true;
1516edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1517edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1518698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eAlphaChanged) {
1519698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f)))
1520698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1521698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1522698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eMatrixChanged) {
1523698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setMatrix(s.matrix))
1524698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1525698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1526698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eTransparentRegionChanged) {
1527698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setTransparentRegionHint(s.transparentRegion))
1528698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1529698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1530698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eVisibilityChanged) {
1531698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setFlags(s.flags, s.mask))
1532698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1533698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1534edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1535698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    return flags;
1536edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1537edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1538edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::screenReleased(int dpy)
1539edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1540edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // this may be called by a signal handler, we can't do too much in here
1541edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    android_atomic_or(eConsoleReleased, &mConsoleSignals);
1542edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    signalEvent();
1543edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1544edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1545edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::screenAcquired(int dpy)
1546edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1547edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // this may be called by a signal handler, we can't do too much in here
1548edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    android_atomic_or(eConsoleAcquired, &mConsoleSignals);
1549edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    signalEvent();
1550edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1551edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1552edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
1553edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
15541d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling    const size_t SIZE = 4096;
1555edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char buffer[SIZE];
1556edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    String8 result;
155799b49840d309727678b77403d6cc9f920111623fMathias Agopian
155899b49840d309727678b77403d6cc9f920111623fMathias Agopian    if (!PermissionCache::checkCallingPermission(sDump)) {
1559edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        snprintf(buffer, SIZE, "Permission Denial: "
1560edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                "can't dump SurfaceFlinger from pid=%d, uid=%d\n",
1561edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                IPCThreadState::self()->getCallingPid(),
1562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                IPCThreadState::self()->getCallingUid());
1563edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        result.append(buffer);
1564edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
15659795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
15669795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // figure out if we're stuck somewhere
15679795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const nsecs_t now = systemTime();
15689795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const nsecs_t inSwapBuffers(mDebugInSwapBuffers);
15699795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const nsecs_t inTransaction(mDebugInTransaction);
15709795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0;
15719795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0;
15729795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
15739795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // Try to get the main lock, but don't insist if we can't
15749795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // (this would indicate SF is stuck, but we want to be able to
15759795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // print something in dumpsys).
15769795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        int retry = 3;
15779795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        while (mStateLock.tryLock()<0 && --retry>=0) {
15789795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            usleep(1000000);
15799795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
15809795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const bool locked(retry >= 0);
15819795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (!locked) {
15828b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber            snprintf(buffer, SIZE,
15839795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "SurfaceFlinger appears to be unresponsive, "
15849795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "dumping anyways (no locks held)\n");
15859795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            result.append(buffer);
15869795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
15879795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
158848b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        /*
158948b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian         * Dump the visible layer list
159048b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian         */
1591edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
1592edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const size_t count = currentLayers.size();
159348b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        snprintf(buffer, SIZE, "Visible layers (count = %d)\n", count);
159448b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        result.append(buffer);
1595edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (size_t i=0 ; i<count ; i++) {
15961b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            const sp<LayerBase>& layer(currentLayers[i]);
15971b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            layer->dump(result, buffer, SIZE);
15981b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            const Layer::State& s(layer->drawingState());
1599edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            s.transparentRegion.dump(result, "transparentRegion");
1600edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->transparentRegionScreen.dump(result, "transparentRegionScreen");
1601edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->visibleRegionScreen.dump(result, "visibleRegionScreen");
1602edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
16031b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
160448b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        /*
160548b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian         * Dump the layers in the purgatory
160648b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian         */
160748b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
160848b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        const size_t purgatorySize =  mLayerPurgatory.size();
160948b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        snprintf(buffer, SIZE, "Purgatory state (%d entries)\n", purgatorySize);
161048b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        result.append(buffer);
161148b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        for (size_t i=0 ; i<purgatorySize ; i++) {
161248b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian            const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
161348b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian            layer->shortDump(result, buffer, SIZE);
161448b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        }
161548b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
161648b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        /*
161748b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian         * Dump SurfaceFlinger global state
161848b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian         */
161948b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
1620ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian        snprintf(buffer, SIZE, "SurfaceFlinger global state:\n");
162148b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        result.append(buffer);
1622ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian
1623ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian        const GLExtensions& extensions(GLExtensions::getInstance());
1624ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian        snprintf(buffer, SIZE, "GLES: %s, %s, %s\n",
1625ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian                extensions.getVendor(),
1626ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian                extensions.getRenderer(),
1627ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian                extensions.getVersion());
1628ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian        result.append(buffer);
1629ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian        snprintf(buffer, SIZE, "EXTS: %s\n", extensions.getExtension());
1630ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian        result.append(buffer);
1631ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian
1632edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mWormholeRegion.dump(result, "WormholeRegion");
1633edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const DisplayHardware& hw(graphicPlane(0).displayHardware());
1634edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        snprintf(buffer, SIZE,
1635edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                "  display frozen: %s, freezeCount=%d, orientation=%d, canDraw=%d\n",
1636edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mFreezeDisplay?"yes":"no", mFreezeCount,
1637edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mCurrentState.orientation, hw.canDraw());
1638edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        result.append(buffer);
16399795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        snprintf(buffer, SIZE,
16409795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                "  last eglSwapBuffers() time: %f us\n"
1641d5e4ef9e439317e2525a51106dbc509d3982de24Mathias Agopian                "  last transaction time     : %f us\n"
1642d5e4ef9e439317e2525a51106dbc509d3982de24Mathias Agopian                "  refresh-rate              : %f fps\n"
1643d5e4ef9e439317e2525a51106dbc509d3982de24Mathias Agopian                "  x-dpi                     : %f\n"
1644d5e4ef9e439317e2525a51106dbc509d3982de24Mathias Agopian                "  y-dpi                     : %f\n",
1645d5e4ef9e439317e2525a51106dbc509d3982de24Mathias Agopian                mLastSwapBufferTime/1000.0,
1646d5e4ef9e439317e2525a51106dbc509d3982de24Mathias Agopian                mLastTransactionTime/1000.0,
1647d5e4ef9e439317e2525a51106dbc509d3982de24Mathias Agopian                hw.getRefreshRate(),
1648d5e4ef9e439317e2525a51106dbc509d3982de24Mathias Agopian                hw.getDpiX(),
1649d5e4ef9e439317e2525a51106dbc509d3982de24Mathias Agopian                hw.getDpiY());
16509795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        result.append(buffer);
16511b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
16529795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (inSwapBuffersDuration || !locked) {
16539795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            snprintf(buffer, SIZE, "  eglSwapBuffers time: %f us\n",
16549795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    inSwapBuffersDuration/1000.0);
16559795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            result.append(buffer);
16569795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
16571b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
16589795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (inTransactionDuration || !locked) {
16599795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            snprintf(buffer, SIZE, "  transaction time: %f us\n",
16609795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    inTransactionDuration/1000.0);
16619795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            result.append(buffer);
16629795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
16631b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
166448b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        /*
166548b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian         * Dump HWComposer state
166648b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian         */
166773d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian        HWComposer& hwc(hw.getHwComposer());
166873d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian        snprintf(buffer, SIZE, "  h/w composer %s and %s\n",
166973d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian                hwc.initCheck()==NO_ERROR ? "present" : "not present",
167053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                (mDebugDisableHWC || mDebugRegion) ? "disabled" : "enabled");
167173d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian        result.append(buffer);
167222da60c3e64cd57535cbba063c07127814a2b52fMathias Agopian        hwc.dump(result, buffer, SIZE, mVisibleLayersSortedByZ);
167373d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian
167448b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        /*
167548b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian         * Dump gralloc state
167648b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian         */
16773330b203039dea366d4981db1408a460134b2d2cMathias Agopian        const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
1678076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        alloc.dump(result);
16791d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling        hw.dump(result);
16809795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
16819795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (locked) {
16829795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            mStateLock.unlock();
16839795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
1684edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1685edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    write(fd, result.string(), result.size());
1686edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1687edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1688edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1689edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::onTransact(
1690edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
1691edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1692edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (code) {
1693edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case CREATE_CONNECTION:
1694698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        case SET_TRANSACTION_STATE:
1695edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case SET_ORIENTATION:
1696edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case FREEZE_DISPLAY:
1697edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case UNFREEZE_DISPLAY:
1698edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case BOOT_FINISHED:
169959119e658a12279e8fff508f8773843de2d90917Mathias Agopian        case TURN_ELECTRON_BEAM_OFF:
17009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        case TURN_ELECTRON_BEAM_ON:
1701edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        {
1702edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // codes that require permission check
1703edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            IPCThreadState* ipc = IPCThreadState::self();
1704edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int pid = ipc->getCallingPid();
1705a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian            const int uid = ipc->getCallingUid();
170699b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
170799b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) {
1708375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                LOGE("Permission Denial: "
1709375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                        "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
1710375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                return PERMISSION_DENIED;
1711edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
17121b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
17131b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
17141b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        case CAPTURE_SCREEN:
17151b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
17161b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            // codes that require permission check
17171b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
17181b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int pid = ipc->getCallingPid();
17191b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int uid = ipc->getCallingUid();
172099b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
172199b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) {
17221b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                LOGE("Permission Denial: "
17231b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                        "can't read framebuffer pid=%d, uid=%d", pid, uid);
17241b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                return PERMISSION_DENIED;
17251b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            }
17261b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
1727edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1728edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
17291b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
1730edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
1731edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
1732b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        CHECK_INTERFACE(ISurfaceComposer, data, reply);
173399b49840d309727678b77403d6cc9f920111623fMathias Agopian        if (UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) {
1734375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
1735375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int pid = ipc->getCallingPid();
1736375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int uid = ipc->getCallingUid();
1737375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            LOGE("Permission Denial: "
1738375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                    "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
1739edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return PERMISSION_DENIED;
1740edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1741edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int n;
1742edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        switch (code) {
174301b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian            case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE
174435b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian            case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE
1745edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1746edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1002:  // SHOW_UPDATES
1747edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                n = data.readInt32();
1748edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDebugRegion = n ? n : (mDebugRegion ? 0 : 1);
174953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
175053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
1751edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1752edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1003:  // SHOW_BACKGROUND
1753edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                n = data.readInt32();
1754edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDebugBackground = n ? 1 : 0;
1755edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1756edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1004:{ // repaint everything
175753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
1758cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
1759cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            }
1760cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            case 1005:{ // force transaction
1761cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
1762cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
1763edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
176435b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian            case 1006:{ // enable/disable GraphicLog
176535b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian                int enabled = data.readInt32();
176635b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian                GraphicLog::getInstance().setEnabled(enabled);
176735b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian                return NO_ERROR;
176835b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian            }
1769edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1007: // set mFreezeCount
1770edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mFreezeCount = data.readInt32();
17710408772e34931351d062f2088b611325ddaa6cdbMathias Agopian                mFreezeDisplayTime = 0;
1772edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
177353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian            case 1008:  // toggle use of hw composer
177453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                n = data.readInt32();
177553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                mDebugDisableHWC = n ? 1 : 0;
177653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
177753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
177853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                return NO_ERROR;
1779a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian            case 1009:  // toggle use of transform hint
1780a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                n = data.readInt32();
1781a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                mDebugDisableTransformHint = n ? 1 : 0;
1782a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                invalidateHwcGeometry();
1783a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                repaintEverything();
1784a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                return NO_ERROR;
1785edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1010:  // interrogate.
178601b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian                reply->writeInt32(0);
1787edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(0);
1788edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(mDebugRegion);
1789edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(mDebugBackground);
1790edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1791edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1013: {
1792edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                Mutex::Autolock _l(mStateLock);
1793edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                const DisplayHardware& hw(graphicPlane(0).displayHardware());
1794edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(hw.getPageFlipCount());
1795edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1796edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return NO_ERROR;
1797edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1798edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1799edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return err;
1800edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1801edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
180253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopianvoid SurfaceFlinger::repaintEverything() {
180353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
18040dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    const Rect bounds(hw.getBounds());
18050dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    setInvalidateRegion(Region(bounds));
180653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian    signalEvent();
180753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian}
180853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian
18090dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopianvoid SurfaceFlinger::setInvalidateRegion(const Region& reg) {
18100dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    Mutex::Autolock _l(mInvalidateLock);
18110dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    mInvalidateRegion = reg;
18120dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian}
18130dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian
18140dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias AgopianRegion SurfaceFlinger::getAndClearInvalidateRegion() {
18150dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    Mutex::Autolock _l(mInvalidateLock);
18160dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    Region reg(mInvalidateRegion);
18170dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    mInvalidateRegion.clear();
18180dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    return reg;
18190dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian}
18200dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian
182159119e658a12279e8fff508f8773843de2d90917Mathias Agopian// ---------------------------------------------------------------------------
182259119e658a12279e8fff508f8773843de2d90917Mathias Agopian
1823118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopianstatus_t SurfaceFlinger::renderScreenToTexture(DisplayID dpy,
1824118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        GLuint* textureName, GLfloat* uOut, GLfloat* vOut)
1825118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{
1826118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    Mutex::Autolock _l(mStateLock);
1827118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    return renderScreenToTextureLocked(dpy, textureName, uOut, vOut);
1828118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
1829118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
18309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::renderScreenToTextureLocked(DisplayID dpy,
18319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        GLuint* textureName, GLfloat* uOut, GLfloat* vOut)
183259119e658a12279e8fff508f8773843de2d90917Mathias Agopian{
183359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
183459119e658a12279e8fff508f8773843de2d90917Mathias Agopian        return INVALID_OPERATION;
183559119e658a12279e8fff508f8773843de2d90917Mathias Agopian
183659119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // get screen geometry
183759119e658a12279e8fff508f8773843de2d90917Mathias Agopian    const DisplayHardware& hw(graphicPlane(dpy).displayHardware());
183859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    const uint32_t hw_w = hw.getWidth();
183959119e658a12279e8fff508f8773843de2d90917Mathias Agopian    const uint32_t hw_h = hw.getHeight();
184059119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLfloat u = 1;
184159119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLfloat v = 1;
184259119e658a12279e8fff508f8773843de2d90917Mathias Agopian
184359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // make sure to clear all GL error flags
184459119e658a12279e8fff508f8773843de2d90917Mathias Agopian    while ( glGetError() != GL_NO_ERROR ) ;
184559119e658a12279e8fff508f8773843de2d90917Mathias Agopian
184659119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // create a FBO
184759119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLuint name, tname;
184859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glGenTextures(1, &tname);
184959119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
18509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
18519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            hw_w, hw_h, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
185259119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (glGetError() != GL_NO_ERROR) {
1853015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian        while ( glGetError() != GL_NO_ERROR ) ;
185459119e658a12279e8fff508f8773843de2d90917Mathias Agopian        GLint tw = (2 << (31 - clz(hw_w)));
185559119e658a12279e8fff508f8773843de2d90917Mathias Agopian        GLint th = (2 << (31 - clz(hw_h)));
18569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
18579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian                tw, th, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
185859119e658a12279e8fff508f8773843de2d90917Mathias Agopian        u = GLfloat(hw_w) / tw;
185959119e658a12279e8fff508f8773843de2d90917Mathias Agopian        v = GLfloat(hw_h) / th;
186059119e658a12279e8fff508f8773843de2d90917Mathias Agopian    }
186159119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glGenFramebuffersOES(1, &name);
186259119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
18639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES,
18649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0);
186559119e658a12279e8fff508f8773843de2d90917Mathias Agopian
18669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // redraw the screen entirely...
1867c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_EXTERNAL_OES);
1868c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_2D);
18699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glClearColor(0,0,0,1);
18709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glClear(GL_COLOR_BUFFER_BIT);
1871a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glMatrixMode(GL_MODELVIEW);
1872a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glLoadIdentity();
18739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
18749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const size_t count = layers.size();
18759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (size_t i=0 ; i<count ; ++i) {
18769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
18779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        layer->drawForSreenShot();
18789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
187959119e658a12279e8fff508f8773843de2d90917Mathias Agopian
1880118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    hw.compositionComplete();
1881118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
18829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // back to main framebuffer
18839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
18849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_SCISSOR_TEST);
18859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDeleteFramebuffersOES(1, &name);
188659119e658a12279e8fff508f8773843de2d90917Mathias Agopian
18879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *textureName = tname;
18889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *uOut = u;
18899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *vOut = v;
18909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
18919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
189259119e658a12279e8fff508f8773843de2d90917Mathias Agopian
18939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// ---------------------------------------------------------------------------
189459119e658a12279e8fff508f8773843de2d90917Mathias Agopian
18959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::electronBeamOffAnimationImplLocked()
18969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
18979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // get screen geometry
18989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
18999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_w = hw.getWidth();
19009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_h = hw.getHeight();
1901a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    const Region screenBounds(hw.getBounds());
190259119e658a12279e8fff508f8773843de2d90917Mathias Agopian
19039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat u, v;
19049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLuint tname;
1905118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    status_t result = renderScreenToTextureLocked(0, &tname, &u, &v);
19069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (result != NO_ERROR) {
19079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return result;
19089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
190959119e658a12279e8fff508f8773843de2d90917Mathias Agopian
19109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat vtx[8];
1911a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    const GLfloat texCoords[4][2] = { {0,0}, {0,v}, {u,v}, {u,0} };
19129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
19139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
19149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
19159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
19169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
19179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
19189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glVertexPointer(2, GL_FLOAT, 0, vtx);
19199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
1920ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    /*
1921ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     * Texture coordinate mapping
1922ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *
1923ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *                 u
1924ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *    1 +----------+---+
1925ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |     |    |   |  image is inverted
1926ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |     V    |   |  w.r.t. the texture
1927ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *  1-v +----------+   |  coordinates
1928ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |              |
1929ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |              |
1930ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |              |
1931ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *    0 +--------------+
1932ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      0              1
1933ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *
1934ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     */
1935ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian
19369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class s_curve_interpolator {
19379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float nbFrames, s, v;
19389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
19399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        s_curve_interpolator(int nbFrames, float s)
19409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : nbFrames(1.0f / (nbFrames-1)), s(s),
19419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian          v(1.0f + expf(-s + 0.5f*s)) {
19429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
19439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float operator()(int f) {
19449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const float x = f * nbFrames;
19459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f;
19469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
19479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
19489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class v_stretch {
19509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
19519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
19529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        v_stretch(uint32_t hw_w, uint32_t hw_h)
19539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
19549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
19559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
19569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w + (hw_w * v);
19579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = hw_h - (hw_h * v);
19589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
19599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
1960ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[0] = x;         vtx[1] = y;
1961ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
1962ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
1963ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
19649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
19659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
19669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class h_stretch {
19689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
19699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
19709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        h_stretch(uint32_t hw_w, uint32_t hw_h)
19719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
197259119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
19739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
19749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w - (hw_w * v);
19759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = 1.0f;
19769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
19779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
1978ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[0] = x;         vtx[1] = y;
1979ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
1980ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
1981ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
19829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
19839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
19849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // the full animation is 24 frames
1986ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    char value[PROPERTY_VALUE_MAX];
1987ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    property_get("debug.sf.electron_frames", value, "24");
1988ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    int nbFrames = (atoi(value) + 1) >> 1;
1989ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    if (nbFrames <= 0) // just in case
1990ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian        nbFrames = 24;
1991ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian
19929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itr(nbFrames, 7.5f);
19939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itg(nbFrames, 8.0f);
19949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itb(nbFrames, 8.5f);
19959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    v_stretch vverts(hw_w, hw_h);
1997a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian
1998a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glMatrixMode(GL_TEXTURE);
1999a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glLoadIdentity();
2000a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glMatrixMode(GL_MODELVIEW);
2001a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glLoadIdentity();
2002a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian
20039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnable(GL_BLEND);
20049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBlendFunc(GL_ONE, GL_ONE);
20059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=0 ; i<nbFrames ; i++) {
20069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float x, y, w, h;
20079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vr = itr(i);
20089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vg = itg(i);
20099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vb = itb(i);
20109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // clear screen
20129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(1,1,1,1);
20139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
20149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glEnable(GL_TEXTURE_2D);
201559119e658a12279e8fff508f8773843de2d90917Mathias Agopian
20169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the red plane
20179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vr);
20189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(1,0,0,1);
20199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
20209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the green plane
20229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vg);
20239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,1,0,1);
20249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
20259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the blue plane
20279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vb);
20289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,0,1,1);
20299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
20309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the white highlight (we use the last vertices)
203259119e658a12279e8fff508f8773843de2d90917Mathias Agopian        glDisable(GL_TEXTURE_2D);
203359119e658a12279e8fff508f8773843de2d90917Mathias Agopian        glColorMask(1,1,1,1);
20349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColor4f(vg, vg, vg, 1);
20359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
20369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
20379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
20389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    h_stretch hverts(hw_w, hw_h);
20409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_BLEND);
20419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_TEXTURE_2D);
20429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
20439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=0 ; i<nbFrames ; i++) {
20449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float v = itg(i);
20459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hverts(vtx, v);
20469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
20479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColor4f(1-v, 1-v, 1-v, 1);
20489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
20499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
20509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
20519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
20539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnable(GL_SCISSOR_TEST);
20549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
20559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDeleteTextures(1, &tname);
2056a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    glDisable(GL_TEXTURE_2D);
2057c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_BLEND);
20589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
20599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
20609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::electronBeamOnAnimationImplLocked()
20629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
20639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    status_t result = PERMISSION_DENIED;
20649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
20669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return INVALID_OPERATION;
20679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // get screen geometry
20709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
20719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_w = hw.getWidth();
20729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_h = hw.getHeight();
20739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const Region screenBounds(hw.bounds());
20749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat u, v;
20769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLuint tname;
20779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    result = renderScreenToTextureLocked(0, &tname, &u, &v);
20789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (result != NO_ERROR) {
20799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return result;
20809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
20819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat vtx[8];
20839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const GLfloat texCoords[4][2] = { {0,v}, {0,0}, {u,0}, {u,v} };
20849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
20859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
20869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
20879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
20889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
20899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
20909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glVertexPointer(2, GL_FLOAT, 0, vtx);
20919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class s_curve_interpolator {
20939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float nbFrames, s, v;
20949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
20959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        s_curve_interpolator(int nbFrames, float s)
20969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : nbFrames(1.0f / (nbFrames-1)), s(s),
20979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian          v(1.0f + expf(-s + 0.5f*s)) {
20989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
20999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float operator()(int f) {
21009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const float x = f * nbFrames;
21019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f;
21029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
21039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
21049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class v_stretch {
21069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
21079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
21089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        v_stretch(uint32_t hw_w, uint32_t hw_h)
21099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
211059119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
21119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
21129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w + (hw_w * v);
21139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = hw_h - (hw_h * v);
21149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
21159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
21169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[0] = x;         vtx[1] = y;
21179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
21189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
21199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
21209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
21219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
21229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class h_stretch {
21249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
21259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
21269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        h_stretch(uint32_t hw_w, uint32_t hw_h)
21279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
21289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
21299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
21309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w - (hw_w * v);
21319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = 1.0f;
21329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
21339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
21349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[0] = x;         vtx[1] = y;
21359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
21369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
21379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
21389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
21399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
21409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2141a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian    // the full animation is 12 frames
2142a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian    int nbFrames = 8;
21439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itr(nbFrames, 7.5f);
21449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itg(nbFrames, 8.0f);
21459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itb(nbFrames, 8.5f);
21469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    h_stretch hverts(hw_w, hw_h);
21489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_BLEND);
21499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_TEXTURE_2D);
21509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
21519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=nbFrames-1 ; i>=0 ; i--) {
21529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float v = itg(i);
21539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hverts(vtx, v);
21549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
21559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColor4f(1-v, 1-v, 1-v, 1);
21569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
21579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
21589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
21599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2160a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian    nbFrames = 4;
21619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    v_stretch vverts(hw_w, hw_h);
21629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnable(GL_BLEND);
21639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBlendFunc(GL_ONE, GL_ONE);
21649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=nbFrames-1 ; i>=0 ; i--) {
21659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float x, y, w, h;
21669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vr = itr(i);
21679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vg = itg(i);
21689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vb = itb(i);
216959119e658a12279e8fff508f8773843de2d90917Mathias Agopian
21709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // clear screen
217159119e658a12279e8fff508f8773843de2d90917Mathias Agopian        glColorMask(1,1,1,1);
21729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
21739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glEnable(GL_TEXTURE_2D);
21749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the red plane
21769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vr);
21779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(1,0,0,1);
21789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
21799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the green plane
21819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vg);
21829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,1,0,1);
21839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
21849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the blue plane
21869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vb);
21879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,0,1,1);
21889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
21899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
219159119e658a12279e8fff508f8773843de2d90917Mathias Agopian    }
219259119e658a12279e8fff508f8773843de2d90917Mathias Agopian
21939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
21949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnable(GL_SCISSOR_TEST);
21959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
219659119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glDeleteTextures(1, &tname);
2197a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    glDisable(GL_TEXTURE_2D);
2198c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_BLEND);
219959119e658a12279e8fff508f8773843de2d90917Mathias Agopian
22009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
22019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
22029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// ---------------------------------------------------------------------------
22049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2205abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOffImplLocked(int32_t mode)
22069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
22079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    DisplayHardware& hw(graphicPlane(0).editDisplayHardware());
22089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (!hw.canDraw()) {
22099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // we're already off
22109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return NO_ERROR;
22119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
22127ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian
22137ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian    // turn off hwc while we're doing the animation
22147ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian    hw.getHwComposer().disable();
22157ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian    // and make sure to turn it back on (if needed) next time we compose
22167ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian    invalidateHwcGeometry();
22177ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian
2218abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    if (mode & ISurfaceComposer::eElectronBeamAnimationOff) {
2219abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        electronBeamOffAnimationImplLocked();
2220abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    }
2221abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian
2222abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    // always clear the whole screen at the end of the animation
2223abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    glClearColor(0,0,0,1);
2224abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    glDisable(GL_SCISSOR_TEST);
2225abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    glClear(GL_COLOR_BUFFER_BIT);
2226abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    glEnable(GL_SCISSOR_TEST);
2227abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    hw.flip( Region(hw.bounds()) );
2228abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian
2229015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian    return NO_ERROR;
223059119e658a12279e8fff508f8773843de2d90917Mathias Agopian}
223159119e658a12279e8fff508f8773843de2d90917Mathias Agopian
223259119e658a12279e8fff508f8773843de2d90917Mathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOff(int32_t mode)
223359119e658a12279e8fff508f8773843de2d90917Mathias Agopian{
223459119e658a12279e8fff508f8773843de2d90917Mathias Agopian    class MessageTurnElectronBeamOff : public MessageBase {
223559119e658a12279e8fff508f8773843de2d90917Mathias Agopian        SurfaceFlinger* flinger;
2236abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        int32_t mode;
223759119e658a12279e8fff508f8773843de2d90917Mathias Agopian        status_t result;
223859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    public:
2239abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        MessageTurnElectronBeamOff(SurfaceFlinger* flinger, int32_t mode)
2240abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            : flinger(flinger), mode(mode), result(PERMISSION_DENIED) {
224159119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
224259119e658a12279e8fff508f8773843de2d90917Mathias Agopian        status_t getResult() const {
224359119e658a12279e8fff508f8773843de2d90917Mathias Agopian            return result;
224459119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
224559119e658a12279e8fff508f8773843de2d90917Mathias Agopian        virtual bool handler() {
224659119e658a12279e8fff508f8773843de2d90917Mathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
2247abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            result = flinger->turnElectronBeamOffImplLocked(mode);
224859119e658a12279e8fff508f8773843de2d90917Mathias Agopian            return true;
224959119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
225059119e658a12279e8fff508f8773843de2d90917Mathias Agopian    };
225159119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2252abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    sp<MessageBase> msg = new MessageTurnElectronBeamOff(this, mode);
225359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    status_t res = postMessageSync(msg);
225459119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (res == NO_ERROR) {
225559119e658a12279e8fff508f8773843de2d90917Mathias Agopian        res = static_cast<MessageTurnElectronBeamOff*>( msg.get() )->getResult();
22569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // work-around: when the power-manager calls us we activate the
22589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // animation. eventually, the "on" animation will be called
22599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // by the power-manager itself
2260abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        mElectronBeamAnimationMode = mode;
226159119e658a12279e8fff508f8773843de2d90917Mathias Agopian    }
226259119e658a12279e8fff508f8773843de2d90917Mathias Agopian    return res;
226359119e658a12279e8fff508f8773843de2d90917Mathias Agopian}
226459119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2265edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
2266edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2267abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOnImplLocked(int32_t mode)
22689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
22699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    DisplayHardware& hw(graphicPlane(0).editDisplayHardware());
22709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (hw.canDraw()) {
22719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // we're already on
22729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return NO_ERROR;
22739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
2274abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    if (mode & ISurfaceComposer::eElectronBeamAnimationOn) {
2275abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        electronBeamOnAnimationImplLocked();
2276abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    }
2277a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian
2278a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian    // make sure to redraw the whole screen when the animation is done
2279a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian    mDirtyRegion.set(hw.bounds());
2280a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian    signalEvent();
2281a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian
2282015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian    return NO_ERROR;
22839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
22849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOn(int32_t mode)
22869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
22879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class MessageTurnElectronBeamOn : public MessageBase {
22889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        SurfaceFlinger* flinger;
2289abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        int32_t mode;
22909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        status_t result;
22919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
2292abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        MessageTurnElectronBeamOn(SurfaceFlinger* flinger, int32_t mode)
2293abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            : flinger(flinger), mode(mode), result(PERMISSION_DENIED) {
22949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
22959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        status_t getResult() const {
22969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return result;
22979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
22989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        virtual bool handler() {
22999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
2300abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            result = flinger->turnElectronBeamOnImplLocked(mode);
23019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return true;
23029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
23039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
23049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2305abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    postMessageAsync( new MessageTurnElectronBeamOn(this, mode) );
23069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
23079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
23089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
23099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// ---------------------------------------------------------------------------
23109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
231174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopianstatus_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy,
231274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        sp<IMemoryHeap>* heap,
231374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t* w, uint32_t* h, PixelFormat* f,
2314bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t sw, uint32_t sh,
2315bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ, uint32_t maxLayerZ)
231674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{
231774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    status_t result = PERMISSION_DENIED;
231874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
231974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // only one display supported for now
232074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
232174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return BAD_VALUE;
232274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
232374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
232474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return INVALID_OPERATION;
232574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
232674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // get screen geometry
232774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const DisplayHardware& hw(graphicPlane(dpy).displayHardware());
232874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const uint32_t hw_w = hw.getWidth();
232974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const uint32_t hw_h = hw.getHeight();
233074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
233174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    if ((sw > hw_w) || (sh > hw_h))
233274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return BAD_VALUE;
233374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
233474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    sw = (!sw) ? hw_w : sw;
233574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    sh = (!sh) ? hw_h : sh;
233674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const size_t size = sw * sh * 4;
233774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
23381c71a47a6db679a3212f0c99e14f330d6da500faMathias Agopian    //LOGD("screenshot: sw=%d, sh=%d, minZ=%d, maxZ=%d",
23391c71a47a6db679a3212f0c99e14f330d6da500faMathias Agopian    //        sw, sh, minLayerZ, maxLayerZ);
2340c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
234174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // make sure to clear all GL error flags
234274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    while ( glGetError() != GL_NO_ERROR ) ;
234374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
234474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // create a FBO
234574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    GLuint name, tname;
234674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glGenRenderbuffersOES(1, &tname);
234774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindRenderbufferOES(GL_RENDERBUFFER_OES, tname);
234874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA8_OES, sw, sh);
234974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glGenFramebuffersOES(1, &name);
235074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
235174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES,
235274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, tname);
235374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
235474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
2355c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
235674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    if (status == GL_FRAMEBUFFER_COMPLETE_OES) {
235774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
235874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // invert everything, b/c glReadPixel() below will invert the FB
235974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glViewport(0, 0, sw, sh);
2360f653b897a449e10d6cbfb6e0812f7b0bb02d6482Mathias Agopian        glScissor(0, 0, sw, sh);
2361ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian        glEnable(GL_SCISSOR_TEST);
236274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_PROJECTION);
236374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glPushMatrix();
236474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glLoadIdentity();
2365ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian        glOrthof(0, hw_w, hw_h, 0, 0, 1);
236674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_MODELVIEW);
236774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
236874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // redraw the screen entirely...
236974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glClearColor(0,0,0,1);
237074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
2371f653b897a449e10d6cbfb6e0812f7b0bb02d6482Mathias Agopian
23729575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        const LayerVector& layers(mDrawingState.layersSortedByZ);
23739575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        const size_t count = layers.size();
237474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        for (size_t i=0 ; i<count ; ++i) {
237574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            const sp<LayerBase>& layer(layers[i]);
2376b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian            const uint32_t flags = layer->drawingState().flags;
2377b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian            if (!(flags & ISurfaceComposer::eLayerHidden)) {
2378b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                const uint32_t z = layer->drawingState().z;
2379b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                if (z >= minLayerZ && z <= maxLayerZ) {
2380b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                    layer->drawForSreenShot();
2381b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                }
2382bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian            }
238374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        }
238474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
238574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // XXX: this is needed on tegra
2386ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian        glEnable(GL_SCISSOR_TEST);
238774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glScissor(0, 0, sw, sh);
238874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
238974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // check for errors and return screen capture
239074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        if (glGetError() != GL_NO_ERROR) {
239174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // error while rendering
239274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            result = INVALID_OPERATION;
239374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        } else {
239474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // allocate shared memory large enough to hold the
239574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // screen capture
239674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            sp<MemoryHeapBase> base(
239774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    new MemoryHeapBase(size, 0, "screen-capture") );
239874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            void* const ptr = base->getBase();
239974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            if (ptr) {
240074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                // capture the screen with glReadPixels()
240174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                glReadPixels(0, 0, sw, sh, GL_RGBA, GL_UNSIGNED_BYTE, ptr);
240274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                if (glGetError() == GL_NO_ERROR) {
240374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *heap = base;
240474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *w = sw;
240574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *h = sh;
240674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *f = PIXEL_FORMAT_RGBA_8888;
240774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    result = NO_ERROR;
240874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                }
240974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            } else {
241074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                result = NO_MEMORY;
241174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            }
241274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        }
241374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glEnable(GL_SCISSOR_TEST);
241474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glViewport(0, 0, hw_w, hw_h);
241574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_PROJECTION);
241674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glPopMatrix();
241774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_MODELVIEW);
241874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    } else {
241974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        result = BAD_VALUE;
242074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    }
242174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
242274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // release FBO resources
242374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
242474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glDeleteRenderbuffersOES(1, &tname);
242574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glDeleteFramebuffersOES(1, &name);
2426e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian
2427e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian    hw.compositionComplete();
2428e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian
24291c71a47a6db679a3212f0c99e14f330d6da500faMathias Agopian    // LOGD("screenshot: result = %s", result<0 ? strerror(result) : "OK");
2430c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
243174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    return result;
243274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian}
243374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
243474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
24351b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopianstatus_t SurfaceFlinger::captureScreen(DisplayID dpy,
24361b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        sp<IMemoryHeap>* heap,
243774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t* width, uint32_t* height, PixelFormat* format,
2438bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t sw, uint32_t sh,
2439bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ, uint32_t maxLayerZ)
24401b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian{
24411b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    // only one display supported for now
24421b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
24431b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        return BAD_VALUE;
24441b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
24451b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
24461b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        return INVALID_OPERATION;
24471b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
24481b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    class MessageCaptureScreen : public MessageBase {
24491b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        SurfaceFlinger* flinger;
24501b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        DisplayID dpy;
24511b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        sp<IMemoryHeap>* heap;
24521b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        uint32_t* w;
24531b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        uint32_t* h;
24541b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        PixelFormat* f;
245574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t sw;
245674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t sh;
2457bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ;
2458bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t maxLayerZ;
24591b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        status_t result;
24601b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    public:
24611b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        MessageCaptureScreen(SurfaceFlinger* flinger, DisplayID dpy,
246274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                sp<IMemoryHeap>* heap, uint32_t* w, uint32_t* h, PixelFormat* f,
2463bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                uint32_t sw, uint32_t sh,
2464bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                uint32_t minLayerZ, uint32_t maxLayerZ)
24651b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            : flinger(flinger), dpy(dpy),
2466bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              heap(heap), w(w), h(h), f(f), sw(sw), sh(sh),
2467bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              minLayerZ(minLayerZ), maxLayerZ(maxLayerZ),
2468bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              result(PERMISSION_DENIED)
24691b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
24701b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
24711b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        status_t getResult() const {
24721b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            return result;
24731b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
24741b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        virtual bool handler() {
24751b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
24761b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
24771b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            // if we have secure windows, never allow the screen capture
24781b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            if (flinger->mSecureFrameBuffer)
24791b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                return true;
24801b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
248174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            result = flinger->captureScreenImplLocked(dpy,
2482bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                    heap, w, h, f, sw, sh, minLayerZ, maxLayerZ);
24831b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
24841b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            return true;
24851b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
24861b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    };
24871b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
24881b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    sp<MessageBase> msg = new MessageCaptureScreen(this,
2489bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian            dpy, heap, width, height, format, sw, sh, minLayerZ, maxLayerZ);
24901b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    status_t res = postMessageSync(msg);
24911b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    if (res == NO_ERROR) {
24921b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        res = static_cast<MessageCaptureScreen*>( msg.get() )->getResult();
24931b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    }
24941b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    return res;
24951b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian}
24961b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
24971b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// ---------------------------------------------------------------------------
24981b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
2499b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<Layer> SurfaceFlinger::getLayer(const sp<ISurface>& sur) const
2500edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2501b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<Layer> result;
2502b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    Mutex::Autolock _l(mStateLock);
2503b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    result = mLayerMap.valueFor( sur->asBinder() ).promote();
2504b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return result;
2505b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
25067303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
2507b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// ---------------------------------------------------------------------------
250896f0819f81293076e652792794a961543e6750d7Mathias Agopian
2509b7e930db175c192464cebdeb49eb56cf6dd60114Mathias AgopianClient::Client(const sp<SurfaceFlinger>& flinger)
2510b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    : mFlinger(flinger), mNameGenerator(1)
2511b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{
2512edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2513edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
251496f0819f81293076e652792794a961543e6750d7Mathias AgopianClient::~Client()
251596f0819f81293076e652792794a961543e6750d7Mathias Agopian{
251696f0819f81293076e652792794a961543e6750d7Mathias Agopian    const size_t count = mLayers.size();
251796f0819f81293076e652792794a961543e6750d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
251896f0819f81293076e652792794a961543e6750d7Mathias Agopian        sp<LayerBaseClient> layer(mLayers.valueAt(i).promote());
251996f0819f81293076e652792794a961543e6750d7Mathias Agopian        if (layer != 0) {
252096f0819f81293076e652792794a961543e6750d7Mathias Agopian            mFlinger->removeLayer(layer);
252196f0819f81293076e652792794a961543e6750d7Mathias Agopian        }
2522edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2523edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2524076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
252596f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t Client::initCheck() const {
2526b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return NO_ERROR;
2527edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2528076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
25294f113740180b6512b43723c4728f262882dc9b45Mathias Agopiansize_t Client::attachLayer(const sp<LayerBaseClient>& layer)
2530edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
25314f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    Mutex::Autolock _l(mLock);
25324f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    size_t name = mNameGenerator++;
253396f0819f81293076e652792794a961543e6750d7Mathias Agopian    mLayers.add(name, layer);
253496f0819f81293076e652792794a961543e6750d7Mathias Agopian    return name;
2535edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2536edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2537b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianvoid Client::detachLayer(const LayerBaseClient* layer)
253896f0819f81293076e652792794a961543e6750d7Mathias Agopian{
25394f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    Mutex::Autolock _l(mLock);
254096f0819f81293076e652792794a961543e6750d7Mathias Agopian    // we do a linear search here, because this doesn't happen often
254196f0819f81293076e652792794a961543e6750d7Mathias Agopian    const size_t count = mLayers.size();
254296f0819f81293076e652792794a961543e6750d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
254396f0819f81293076e652792794a961543e6750d7Mathias Agopian        if (mLayers.valueAt(i) == layer) {
254496f0819f81293076e652792794a961543e6750d7Mathias Agopian            mLayers.removeItemsAt(i, 1);
254596f0819f81293076e652792794a961543e6750d7Mathias Agopian            break;
254696f0819f81293076e652792794a961543e6750d7Mathias Agopian        }
254796f0819f81293076e652792794a961543e6750d7Mathias Agopian    }
254896f0819f81293076e652792794a961543e6750d7Mathias Agopian}
25494f113740180b6512b43723c4728f262882dc9b45Mathias Agopiansp<LayerBaseClient> Client::getLayerUser(int32_t i) const
25504f113740180b6512b43723c4728f262882dc9b45Mathias Agopian{
25514f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    Mutex::Autolock _l(mLock);
2552076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBaseClient> lbc;
25534f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    wp<LayerBaseClient> layer(mLayers.valueFor(i));
255496f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (layer != 0) {
255596f0819f81293076e652792794a961543e6750d7Mathias Agopian        lbc = layer.promote();
255696f0819f81293076e652792794a961543e6750d7Mathias Agopian        LOGE_IF(lbc==0, "getLayerUser(name=%d) is dead", int(i));
2557076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
2558076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return lbc;
2559edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2560edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2561a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
2562a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianstatus_t Client::onTransact(
2563a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
2564a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian{
2565a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // these must be checked
2566a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     IPCThreadState* ipc = IPCThreadState::self();
2567a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     const int pid = ipc->getCallingPid();
2568a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     const int uid = ipc->getCallingUid();
2569a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     const int self_pid = getpid();
2570a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     if (UNLIKELY(pid != self_pid && uid != AID_GRAPHICS && uid != 0)) {
2571a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian         // we're called from a different process, do the real check
257299b49840d309727678b77403d6cc9f920111623fMathias Agopian         if (!PermissionCache::checkCallingPermission(sAccessSurfaceFlinger))
2573a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian         {
2574a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian             LOGE("Permission Denial: "
2575a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                     "can't openGlobalTransaction pid=%d, uid=%d", pid, uid);
2576a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian             return PERMISSION_DENIED;
2577a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian         }
2578a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     }
2579a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     return BnSurfaceComposerClient::onTransact(code, data, reply, flags);
2580edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2581a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
2582a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
258396f0819f81293076e652792794a961543e6750d7Mathias Agopiansp<ISurface> Client::createSurface(
25840ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        ISurfaceComposerClient::surface_data_t* params,
2585b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        const String8& name,
2586b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
2587edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t flags)
2588edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2589b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    /*
2590a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     * createSurface must be called from the GL thread so that it can
2591a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     * have access to the GL context.
2592b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     */
2593b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
2594a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    class MessageCreateSurface : public MessageBase {
2595a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        sp<ISurface> result;
2596a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        SurfaceFlinger* flinger;
2597a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        ISurfaceComposerClient::surface_data_t* params;
2598a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        Client* client;
2599a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        const String8& name;
2600a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        DisplayID display;
2601a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        uint32_t w, h;
2602a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        PixelFormat format;
2603a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        uint32_t flags;
2604a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    public:
2605a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        MessageCreateSurface(SurfaceFlinger* flinger,
2606a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                ISurfaceComposerClient::surface_data_t* params,
2607a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                const String8& name, Client* client,
2608a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
2609a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                uint32_t flags)
2610a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            : flinger(flinger), params(params), client(client), name(name),
2611a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian              display(display), w(w), h(h), format(format), flags(flags)
2612a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        {
2613579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        }
2614a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        sp<ISurface> getResult() const { return result; }
2615a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        virtual bool handler() {
2616a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            result = flinger->createSurface(params, name, client,
2617a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                    display, w, h, format, flags);
2618a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            return true;
2619b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        }
2620a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    };
2621b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
2622a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    sp<MessageBase> msg = new MessageCreateSurface(mFlinger.get(),
2623a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            params, name, this, display, w, h, format, flags);
2624a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    mFlinger->postMessageSync(msg);
2625a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    return static_cast<MessageCreateSurface*>( msg.get() )->getResult();
2626b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
2627a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianstatus_t Client::destroySurface(SurfaceID sid) {
2628a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    return mFlinger->removeSurface(this, sid);
2629b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
2630b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
2631b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// ---------------------------------------------------------------------------
2632edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
26339a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::GraphicBufferAlloc() {}
26349a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
26359a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::~GraphicBufferAlloc() {}
26369a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
26379a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h,
2638d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        PixelFormat format, uint32_t usage, status_t* error) {
26399a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(w, h, format, usage));
26409a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    status_t err = graphicBuffer->initCheck();
2641d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian    *error = err;
2642a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (err != 0 || graphicBuffer->handle == 0) {
2643d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        if (err == NO_MEMORY) {
2644d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian            GraphicBuffer::dumpAllocationsToSystemLog();
2645d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        }
2646a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        LOGE("GraphicBufferAlloc::createGraphicBuffer(w=%d, h=%d) "
2647a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian             "failed (%s), handle=%p",
2648a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                w, h, strerror(-err), graphicBuffer->handle);
26499a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis        return 0;
26509a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    }
26519a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    return graphicBuffer;
26529a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis}
26539a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
26549a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis// ---------------------------------------------------------------------------
26559a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
2656edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane::GraphicPlane()
2657edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    : mHw(0)
2658edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2659edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2660edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2661edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane::~GraphicPlane() {
2662edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    delete mHw;
2663edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2664edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2665edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool GraphicPlane::initialized() const {
2666edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return mHw ? true : false;
2667edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2668edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
26692b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianint GraphicPlane::getWidth() const {
26702b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    return mWidth;
2671edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2672edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
26732b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianint GraphicPlane::getHeight() const {
26742b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    return mHeight;
26752b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian}
26762b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
26772b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianvoid GraphicPlane::setDisplayHardware(DisplayHardware *hw)
26782b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian{
26792b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mHw = hw;
26802b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
26812b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    // initialize the display orientation transform.
26822b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    // it's a constant that should come from the display driver.
26832b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    int displayOrientation = ISurfaceComposer::eOrientationDefault;
26842b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    char property[PROPERTY_VALUE_MAX];
26852b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    if (property_get("ro.sf.hwrotation", property, NULL) > 0) {
26862b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        //displayOrientation
26872b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        switch (atoi(property)) {
26882b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        case 90:
26892b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            displayOrientation = ISurfaceComposer::eOrientation90;
26902b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            break;
26912b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        case 270:
26922b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            displayOrientation = ISurfaceComposer::eOrientation270;
26932b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            break;
26942b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        }
26952b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    }
26962b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
26972b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float w = hw->getWidth();
26982b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float h = hw->getHeight();
26992b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    GraphicPlane::orientationToTransfrom(displayOrientation, w, h,
27002b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            &mDisplayTransform);
27012b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    if (displayOrientation & ISurfaceComposer::eOrientationSwapMask) {
27022b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayWidth = h;
27032b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayHeight = w;
27042b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    } else {
27052b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayWidth = w;
27062b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayHeight = h;
27072b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    }
27082b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
27092b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    setOrientation(ISurfaceComposer::eOrientationDefault);
2710edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2711edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2712edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t GraphicPlane::orientationToTransfrom(
2713edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int orientation, int w, int h, Transform* tr)
2714eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian{
2715eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    uint32_t flags = 0;
2716edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (orientation) {
2717edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientationDefault:
2718eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_0;
2719eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        break;
2720edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientation90:
2721eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_90;
2722edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
2723edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientation180:
2724eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_180;
2725edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
2726edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientation270:
2727eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_270;
2728edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
2729edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    default:
2730edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return BAD_VALUE;
2731edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2732eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    tr->set(flags, w, h);
2733edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
2734edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2735edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2736edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t GraphicPlane::setOrientation(int orientation)
2737edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2738edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // If the rotation can be handled in hardware, this is where
2739edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // the magic should happen.
27402b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
27412b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const DisplayHardware& hw(displayHardware());
27422b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float w = mDisplayWidth;
27432b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float h = mDisplayHeight;
27442b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mWidth = int(w);
27452b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mHeight = int(h);
27462b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
27472b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    Transform orientationTransform;
2748eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    GraphicPlane::orientationToTransfrom(orientation, w, h,
2749eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian            &orientationTransform);
2750eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    if (orientation & ISurfaceComposer::eOrientationSwapMask) {
2751eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        mWidth = int(h);
2752eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        mHeight = int(w);
2753edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2754eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian
27550d1318b974feba2e6ff13e36a1781343c2fce045Mathias Agopian    mOrientation = orientation;
27562b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mGlobalTransform = mDisplayTransform * orientationTransform;
2757edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
2758edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2759edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2760edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst DisplayHardware& GraphicPlane::displayHardware() const {
2761edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return *mHw;
2762edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2763edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
276459119e658a12279e8fff508f8773843de2d90917Mathias AgopianDisplayHardware& GraphicPlane::editDisplayHardware() {
276559119e658a12279e8fff508f8773843de2d90917Mathias Agopian    return *mHw;
276659119e658a12279e8fff508f8773843de2d90917Mathias Agopian}
276759119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2768edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst Transform& GraphicPlane::transform() const {
2769edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return mGlobalTransform;
2770edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2771edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2772076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias AgopianEGLDisplay GraphicPlane::getEGLDisplay() const {
2773076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return mHw->getEGLDisplay();
2774076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
2775076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
2776edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
2777edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2778edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
2779