SurfaceFlinger.cpp revision 28378392fd5aa3e0a392c9eb64634055678c3987
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"
53edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h"
54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
55edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "DisplayHardware/DisplayHardware.h"
56a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian#include "DisplayHardware/HWComposer.h"
57edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
58a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian#include <private/surfaceflinger/SharedBufferStack.h>
59a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
60a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian/* ideally AID_GRAPHICS would be in a semi-public header
61a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian * or there would be a way to map a user/group name to its id
62a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian */
63a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian#ifndef AID_GRAPHICS
64a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian#define AID_GRAPHICS 1003
65a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian#endif
66a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian
67edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DISPLAY_COUNT       1
68edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
7299b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sHardwareTest("android.permission.HARDWARE_TEST");
7399b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER");
7499b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER");
7599b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sDump("android.permission.DUMP");
7699b49840d309727678b77403d6cc9f920111623fMathias Agopian
7799b49840d309727678b77403d6cc9f920111623fMathias Agopian// ---------------------------------------------------------------------------
7899b49840d309727678b77403d6cc9f920111623fMathias Agopian
79edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::SurfaceFlinger()
80edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    :   BnSurfaceComposer(), Thread(false),
81edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mTransactionFlags(0),
8228378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        mTransationPending(false),
83076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved(false),
84edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mBootTime(systemTime()),
85edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mVisibleRegionsDirty(false),
86a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        mHwWorkListDirty(false),
87edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mFreezeDisplay(false),
88abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        mElectronBeamAnimationMode(0),
89edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mFreezeCount(0),
90bcef13b666c7459241235bc6209837ae81884d2fThe Android Open Source Project        mFreezeDisplayTime(0),
91edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDebugRegion(0),
92edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDebugBackground(0),
938afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian        mDebugDDMS(0),
9473d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian        mDebugDisableHWC(0),
95a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian        mDebugDisableTransformHint(0),
969795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInSwapBuffers(0),
979795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastSwapBufferTime(0),
989795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInTransaction(0),
999795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastTransactionTime(0),
1003330b203039dea366d4981db1408a460134b2d2cMathias Agopian        mBootFinished(false),
101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mConsoleSignals(0),
102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mSecureFrameBuffer(0)
103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    init();
105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::init()
108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    LOGI("SurfaceFlinger is starting");
110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // debugging stuff...
112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char value[PROPERTY_VALUE_MAX];
1138afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    property_get("debug.sf.showupdates", value, "0");
115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDebugRegion = atoi(value);
1168afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    property_get("debug.sf.showbackground", value, "0");
118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDebugBackground = atoi(value);
119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1208afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    property_get("debug.sf.ddms", value, "0");
1218afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    mDebugDDMS = atoi(value);
1228afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    if (mDebugDDMS) {
1238afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian        DdmConnection::start(getServiceName());
1248afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    }
1258afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
12678fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian    LOGI_IF(mDebugRegion,       "showupdates enabled");
12778fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian    LOGI_IF(mDebugBackground,   "showbackground enabled");
1288afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    LOGI_IF(mDebugDDMS,         "DDMS debugging enabled");
129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::~SurfaceFlinger()
132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDeleteTextures(1, &mWormholeTexName);
134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1367303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopiansp<IMemoryHeap> SurfaceFlinger::getCblk() const
137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1387303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    return mServerHeap;
139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1417e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopiansp<ISurfaceComposerClient> SurfaceFlinger::createConnection()
142edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
14396f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<ISurfaceComposerClient> bclient;
14496f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<Client> client(new Client(this));
14596f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = client->initCheck();
14696f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR) {
14796f0819f81293076e652792794a961543e6750d7Mathias Agopian        bclient = client;
148edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
149edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return bclient;
150edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
151edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1529a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc()
1539a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis{
1549a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc());
1559a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    return gba;
1569a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis}
157b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst GraphicPlane& SurfaceFlinger::graphicPlane(int dpy) const
159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    LOGE_IF(uint32_t(dpy) >= DISPLAY_COUNT, "Invalid DisplayID %d", dpy);
161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(mGraphicPlanes[dpy]);
162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return plane;
163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane& SurfaceFlinger::graphicPlane(int dpy)
166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return const_cast<GraphicPlane&>(
168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const_cast<SurfaceFlinger const *>(this)->graphicPlane(dpy));
169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::bootFinished()
172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t now = systemTime();
174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t duration = now - mBootTime;
1758b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber    LOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
1763330b203039dea366d4981db1408a460134b2d2cMathias Agopian    mBootFinished = true;
1771f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
1781f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // wait patiently for the window manager death
1791f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    const String16 name("window");
1801f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    sp<IBinder> window(defaultServiceManager()->getService(name));
1811f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    if (window != 0) {
1821f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian        window->linkToDeath(this);
1831f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    }
1841f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
1851f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // stop boot animation
186a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    property_set("ctl.stop", "bootanim");
187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1891f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopianvoid SurfaceFlinger::binderDied(const wp<IBinder>& who)
1901f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian{
1911f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // the window manager died on us. prepare its eulogy.
1921f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
1931f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // unfreeze the screen in case it was... frozen
1941f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    mFreezeDisplayTime = 0;
1951f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    mFreezeCount = 0;
1961f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    mFreezeDisplay = false;
1971f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
1981f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // reset screen orientation
1991f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    setOrientation(0, eOrientationDefault, 0);
2001f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
2011f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // restart the boot-animation
2021f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    property_set("ctl.start", "bootanim");
2031f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian}
2041f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
205edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::onFirstRef()
206edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
207edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY);
208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
209edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // Wait for the main thread to be done with its initialization
210edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mReadyToRunBarrier.wait();
211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic inline uint16_t pack565(int r, int g, int b) {
214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return (r<<11)|(g<<5)|b;
215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
217edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::readyToRun()
218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    LOGI(   "SurfaceFlinger's main thread ready to run. "
220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            "Initializing graphics H/W...");
221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // we only support one display currently
223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int dpy = 0;
224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    {
226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // initialize the main display
227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GraphicPlane& plane(graphicPlane(dpy));
228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        DisplayHardware* const hw = new DisplayHardware(this, dpy);
229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        plane.setDisplayHardware(hw);
230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2327303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    // create the shared control-block
2337303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    mServerHeap = new MemoryHeapBase(4096,
2347303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian            MemoryHeapBase::READ_ONLY, "SurfaceFlinger read-only heap");
2357303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    LOGE_IF(mServerHeap==0, "can't create shared memory dealer");
2368b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
2377303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    mServerCblk = static_cast<surface_flinger_cblk_t*>(mServerHeap->getBase());
2387303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    LOGE_IF(mServerCblk==0, "can't get to shared control block's address");
2398b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
2407303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    new(mServerCblk) surface_flinger_cblk_t;
2417303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize primary screen
243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // (other display should be initialized in the same manner, but
244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // asynchronously, as they could come and go. None of this is supported
245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // yet).
246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(graphicPlane(dpy));
247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw = plane.displayHardware();
248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint32_t w = hw.getWidth();
249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint32_t h = hw.getHeight();
250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint32_t f = hw.getFormat();
251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    hw.makeCurrent();
252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize the shared control block
254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mServerCblk->connected |= 1<<dpy;
255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    display_cblk_t* dcblk = mServerCblk->displays + dpy;
256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    memset(dcblk, 0, sizeof(display_cblk_t));
2572b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    dcblk->w            = plane.getWidth();
2582b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    dcblk->h            = plane.getHeight();
259edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->format       = f;
260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->orientation  = ISurfaceComposer::eOrientationDefault;
261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->xdpi         = hw.getDpiX();
262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->ydpi         = hw.getDpiY();
263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->fps          = hw.getRefreshRate();
264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->density      = hw.getDensity();
265edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
266edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // Initialize OpenGL|ES
267edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
2688b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber    glPixelStorei(GL_PACK_ALIGNMENT, 4);
269edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glEnableClientState(GL_VERTEX_ARRAY);
270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glEnable(GL_SCISSOR_TEST);
271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glShadeModel(GL_FLAT);
272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_DITHER);
273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_CULL_FACE);
274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint16_t g0 = pack565(0x0F,0x1F,0x0F);
276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint16_t g1 = pack565(0x17,0x2f,0x17);
2779575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    const uint16_t wormholeTexData[4] = { g0, g1, g1, g0 };
278edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glGenTextures(1, &mWormholeTexName);
279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glBindTexture(GL_TEXTURE_2D, mWormholeTexName);
280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
284edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0,
2859575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis            GL_RGB, GL_UNSIGNED_SHORT_5_6_5, wormholeTexData);
2869575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis
2879575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    const uint16_t protTexData[] = { pack565(0x03, 0x03, 0x03) };
2889575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glGenTextures(1, &mProtectedTexName);
2899575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glBindTexture(GL_TEXTURE_2D, mProtectedTexName);
2909575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2919575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2929575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
2939575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
2949575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0,
2959575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis            GL_RGB, GL_UNSIGNED_SHORT_5_6_5, protTexData);
296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glViewport(0, 0, w, h);
298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glMatrixMode(GL_PROJECTION);
299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glLoadIdentity();
300ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    // put the origin in the left-bottom corner
301ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    glOrthof(0, w, 0, h, 0, 1); // l=0, r=w ; b=0, t=h
302edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mReadyToRunBarrier.open();
304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     *  We're now ready to accept clients...
307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
309a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    // start boot animation
310a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    property_set("ctl.start", "bootanim");
3118b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
312edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
313edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
314edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
315edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if 0
317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark -
318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark Events Handler
319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif
320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::waitForEvent()
322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
323f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    while (true) {
324f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        nsecs_t timeout = -1;
3250408772e34931351d062f2088b611325ddaa6cdbMathias Agopian        const nsecs_t freezeDisplayTimeout = ms2ns(5000);
326f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        if (UNLIKELY(isFrozen())) {
327f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            // wait 5 seconds
328f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            const nsecs_t now = systemTime();
329f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            if (mFreezeDisplayTime == 0) {
330f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian                mFreezeDisplayTime = now;
331f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            }
332f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            nsecs_t waitTime = freezeDisplayTimeout - (now - mFreezeDisplayTime);
333f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            timeout = waitTime>0 ? waitTime : 0;
334bcef13b666c7459241235bc6209837ae81884d2fThe Android Open Source Project        }
335f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian
336bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        sp<MessageBase> msg = mEventQueue.waitMessage(timeout);
3370408772e34931351d062f2088b611325ddaa6cdbMathias Agopian
3380408772e34931351d062f2088b611325ddaa6cdbMathias Agopian        // see if we timed out
3390408772e34931351d062f2088b611325ddaa6cdbMathias Agopian        if (isFrozen()) {
3400408772e34931351d062f2088b611325ddaa6cdbMathias Agopian            const nsecs_t now = systemTime();
3410408772e34931351d062f2088b611325ddaa6cdbMathias Agopian            nsecs_t frozenTime = (now - mFreezeDisplayTime);
3420408772e34931351d062f2088b611325ddaa6cdbMathias Agopian            if (frozenTime >= freezeDisplayTimeout) {
343edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                // we timed out and are still frozen
344edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                LOGW("timeout expired mFreezeDisplay=%d, mFreezeCount=%d",
345edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        mFreezeDisplay, mFreezeCount);
3460408772e34931351d062f2088b611325ddaa6cdbMathias Agopian                mFreezeDisplayTime = 0;
347edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mFreezeCount = 0;
348bcef13b666c7459241235bc6209837ae81884d2fThe Android Open Source Project                mFreezeDisplay = false;
3490408772e34931351d062f2088b611325ddaa6cdbMathias Agopian            }
3500408772e34931351d062f2088b611325ddaa6cdbMathias Agopian        }
3510408772e34931351d062f2088b611325ddaa6cdbMathias Agopian
3520408772e34931351d062f2088b611325ddaa6cdbMathias Agopian        if (msg != 0) {
3530408772e34931351d062f2088b611325ddaa6cdbMathias Agopian            switch (msg->what) {
3540408772e34931351d062f2088b611325ddaa6cdbMathias Agopian                case MessageQueue::INVALIDATE:
3550408772e34931351d062f2088b611325ddaa6cdbMathias Agopian                    // invalidate message, just return to the main loop
3560408772e34931351d062f2088b611325ddaa6cdbMathias Agopian                    return;
357edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
358edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
359edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
360edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
361edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
362edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::signalEvent() {
363f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    mEventQueue.invalidate();
364edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
365edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
366582270d69db94286a248bd829f1ae6f910d45124Jamie Gennisbool SurfaceFlinger::authenticateSurfaceTexture(
367582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis        const sp<ISurfaceTexture>& surfaceTexture) const {
368134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    Mutex::Autolock _l(mStateLock);
369582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis    sp<IBinder> surfaceTextureBinder(surfaceTexture->asBinder());
370134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
371134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // Check the visible layer list for the ISurface
372134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
373134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    size_t count = currentLayers.size();
374134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    for (size_t i=0 ; i<count ; i++) {
375134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        const sp<LayerBase>& layer(currentLayers[i]);
376134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        sp<LayerBaseClient> lbc(layer->getLayerBaseClient());
377582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis        if (lbc != NULL) {
378582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder();
379582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            if (lbcBinder == surfaceTextureBinder) {
380582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis                return true;
381582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            }
382134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        }
383134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    }
384134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
385134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // Check the layers in the purgatory.  This check is here so that if a
386582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis    // SurfaceTexture gets destroyed before all the clients are done using it,
387582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis    // the error will not be reported as "surface XYZ is not authenticated", but
388134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // will instead fail later on when the client tries to use the surface,
389134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // which should be reported as "surface XYZ returned an -ENODEV".  The
390134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // purgatorized layers are no less authentic than the visible ones, so this
391134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // should not cause any harm.
392134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    size_t purgatorySize =  mLayerPurgatory.size();
393134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    for (size_t i=0 ; i<purgatorySize ; i++) {
394134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
395134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        sp<LayerBaseClient> lbc(layer->getLayerBaseClient());
396582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis        if (lbc != NULL) {
397582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder();
398582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            if (lbcBinder == surfaceTextureBinder) {
399582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis                return true;
400582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            }
401134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        }
402134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    }
403134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
404134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    return false;
405134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis}
406134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
407bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg,
408bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        nsecs_t reltime, uint32_t flags)
409edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
410bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    return mEventQueue.postMessage(msg, reltime, flags);
411bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian}
412bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
413bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,
414bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        nsecs_t reltime, uint32_t flags)
415bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian{
416bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    status_t res = mEventQueue.postMessage(msg, reltime, flags);
417bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    if (res == NO_ERROR) {
418bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        msg->wait();
419bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    }
420bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    return res;
421edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
422edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
423edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
424edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if 0
425edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark -
426edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark Main loop
427edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif
428edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
429edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool SurfaceFlinger::threadLoop()
430edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
431edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    waitForEvent();
432edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
433edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // check for transactions
434edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(mConsoleSignals)) {
435edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        handleConsoleEvents();
436edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
437edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
438698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    // if we're in a global transaction, don't do anything.
439698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
440698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    uint32_t transactionFlags = peekTransactionFlags(mask);
441698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    if (UNLIKELY(transactionFlags)) {
442698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        handleTransaction(transactionFlags);
443edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
444edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
445edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // post surfaces (if needed)
446edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    handlePageFlip();
447edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
448a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    if (UNLIKELY(mHwWorkListDirty)) {
449a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        // build the h/w work list
450a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        handleWorkList();
451a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
452a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
453edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw(graphicPlane(0).displayHardware());
4548a77baaa11cb90f84d24f345463a856495be81a2Mathias Agopian    if (LIKELY(hw.canDraw() && !isFrozen())) {
455edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // repaint the framebuffer (if needed)
45635b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian
45735b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        const int index = hw.getCurrentBufferIndex();
45835b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        GraphicLog& logger(GraphicLog::getInstance());
45935b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian
46035b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        logger.log(GraphicLog::SF_REPAINT, index);
461edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        handleRepaint();
462edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
46374faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian        // inform the h/w that we're done compositing
46435b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        logger.log(GraphicLog::SF_COMPOSITION_COMPLETE, index);
46574faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian        hw.compositionComplete();
46674faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian
46735b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        logger.log(GraphicLog::SF_SWAP_BUFFERS, index);
4688392b504bdf63ac7820c79c7217a89f2b2411bd0Antti Hatala        postFramebuffer();
4698392b504bdf63ac7820c79c7217a89f2b2411bd0Antti Hatala
47035b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        logger.log(GraphicLog::SF_REPAINT_DONE, index);
471edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
472edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // pretend we did the post
473e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian        hw.compositionComplete();
474edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        usleep(16667); // 60 fps period
475edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
476edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return true;
477edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
478edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
479edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer()
480edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
4810656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian    if (!mSwapRegion.isEmpty()) {
482edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const DisplayHardware& hw(graphicPlane(0).displayHardware());
4839795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const nsecs_t now = systemTime();
4849795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInSwapBuffers = now;
4850656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian        hw.flip(mSwapRegion);
4869795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastSwapBufferTime = systemTime() - now;
4879795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInSwapBuffers = 0;
4880656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian        mSwapRegion.clear();
489edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
490edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
491edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
492edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleConsoleEvents()
493edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
494edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // something to do with the console
495edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw = graphicPlane(0).displayHardware();
496edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
497edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int what = android_atomic_and(0, &mConsoleSignals);
498edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (what & eConsoleAcquired) {
499edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        hw.acquireScreen();
5009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // this is a temporary work-around, eventually this should be called
5019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // by the power-manager
502abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        SurfaceFlinger::turnElectronBeamOn(mElectronBeamAnimationMode);
503edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
504edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
505edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (what & eConsoleReleased) {
50659119e658a12279e8fff508f8773843de2d90917Mathias Agopian        if (hw.isScreenAcquired()) {
507edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            hw.releaseScreen();
508edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
509edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
510edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
511edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDirtyRegion.set(hw.bounds());
512edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
513edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
514edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
515edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
516ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    Mutex::Autolock _l(mStateLock);
517ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    const nsecs_t now = systemTime();
518ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = now;
519ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
520ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // Here we're guaranteed that some transaction flags are set
521ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // so we can call handleTransactionLocked() unconditionally.
522ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // We call getTransactionFlags(), which will also clear the flags,
523ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // with mStateLock held to guarantee that mCurrentState won't change
524ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // until the transaction is committed.
525ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
526ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
527ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    transactionFlags = getTransactionFlags(mask);
528ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    handleTransactionLocked(transactionFlags);
529ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
530ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mLastTransactionTime = systemTime() - now;
531ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = 0;
532ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    invalidateHwcGeometry();
533ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // here the transaction has been committed
5343d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian}
535edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
536ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopianvoid SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
5373d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{
5383d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    const LayerVector& currentLayers(mCurrentState.layersSortedByZ);
539edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t count = currentLayers.size();
540edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
541edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
542edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Traversal of the children
543edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * (perform the transaction for each of them if needed)
544edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
545edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
546edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const bool layersNeedTransaction = transactionFlags & eTraversalNeeded;
547edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (layersNeedTransaction) {
548edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (size_t i=0 ; i<count ; i++) {
549076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            const sp<LayerBase>& layer = currentLayers[i];
550edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
551edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (!trFlags) continue;
552edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
553edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const uint32_t flags = layer->doTransaction(0);
554edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (flags & Layer::eVisibleRegion)
555edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mVisibleRegionsDirty = true;
556edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
557edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
558edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
559edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
560edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Perform our own transaction if needed
561edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
563edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (transactionFlags & eTransactionNeeded) {
564edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (mCurrentState.orientation != mDrawingState.orientation) {
565edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // the orientation has changed, recompute all visible regions
566edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // and invalidate everything.
567edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
568edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int dpy = 0;
569edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int orientation = mCurrentState.orientation;
57021230c6410bdab13cd2bd274da54b1e4061b6035Jeff Brown            // Currently unused: const uint32_t flags = mCurrentState.orientationFlags;
571edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            GraphicPlane& plane(graphicPlane(dpy));
572edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            plane.setOrientation(orientation);
573edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
574edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // update the shared control block
575edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const DisplayHardware& hw(plane.displayHardware());
576edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            volatile display_cblk_t* dcblk = mServerCblk->displays + dpy;
577edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dcblk->orientation = orientation;
5782b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            dcblk->w = plane.getWidth();
5792b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            dcblk->h = plane.getHeight();
580edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
581edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
582edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mDirtyRegion.set(hw.bounds());
583edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
584edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
585edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (mCurrentState.freezeDisplay != mDrawingState.freezeDisplay) {
586edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // freezing or unfreezing the display -> trigger animation if needed
587edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mFreezeDisplay = mCurrentState.freezeDisplay;
588064e1e672e62094b32f8cf7a77a3b04c3309dc79Mathias Agopian            if (mFreezeDisplay)
589064e1e672e62094b32f8cf7a77a3b04c3309dc79Mathias Agopian                 mFreezeDisplayTime = 0;
590edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
591edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5920aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        if (currentLayers.size() > mDrawingState.layersSortedByZ.size()) {
5930aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            // layers have been added
594edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
595edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
596edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5970aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        // some layers might have been removed, so
5980aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        // we need to update the regions they're exposing.
5990aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        if (mLayersRemoved) {
60048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian            mLayersRemoved = false;
601edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
6020aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            const LayerVector& previousLayers(mDrawingState.layersSortedByZ);
6033d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian            const size_t count = previousLayers.size();
6043d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian            for (size_t i=0 ; i<count ; i++) {
6050aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                const sp<LayerBase>& layer(previousLayers[i]);
6060aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                if (currentLayers.indexOf( layer ) < 0) {
6070aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                    // this layer is not visible anymore
6085d7126b625c8c4a7b945e8c247b63abff7bc13b6Mathias Agopian                    mDirtyRegionRemovedLayer.orSelf(layer->visibleRegionScreen);
6090aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                }
6100aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            }
611edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
612edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
613edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
614edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    commitTransaction();
615edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
616edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
617edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectsp<FreezeLock> SurfaceFlinger::getFreezeLock() const
618edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
619edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return new FreezeLock(const_cast<SurfaceFlinger *>(this));
620edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
621edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
622edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::computeVisibleRegions(
6231bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian    const LayerVector& currentLayers, Region& dirtyRegion, Region& opaqueRegion)
624edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
625edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(graphicPlane(0));
626edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Transform& planeTransform(plane.transform());
627ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian    const DisplayHardware& hw(plane.displayHardware());
628ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian    const Region screenRegion(hw.bounds());
629edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
630edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveOpaqueLayers;
631edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveCoveredLayers;
632edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region dirty;
633edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
634edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    bool secureFrameBuffer = false;
635edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
636edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t i = currentLayers.size();
637edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    while (i--) {
638076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        const sp<LayerBase>& layer = currentLayers[i];
639edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->validateVisibility(planeTransform);
640edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
641edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // start with the whole surface at its current location
642970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian        const Layer::State& s(layer->drawingState());
643edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
644ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
645ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * opaqueRegion: area of a surface that is fully opaque.
646ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
647edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region opaqueRegion;
648ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
649ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
650ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visibleRegion: area of a surface that is visible on screen
651ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * and not fully transparent. This is essentially the layer's
652ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * footprint minus the opaque regions above it.
653ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * Areas covered by a translucent surface are considered visible.
654ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
655edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region visibleRegion;
656ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
657ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
658ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * coveredRegion: area of a surface that is covered by all
659ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visible regions above it (which includes the translucent areas).
660ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
661edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region coveredRegion;
662ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
663ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
664ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // handle hidden surfaces by setting the visible region to empty
665970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian        if (LIKELY(!(s.flags & ISurfaceComposer::eLayerHidden) && s.alpha)) {
666a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            const bool translucent = !layer->isOpaque();
667970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian            const Rect bounds(layer->visibleBounds());
668edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            visibleRegion.set(bounds);
669ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            visibleRegion.andSelf(screenRegion);
670ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            if (!visibleRegion.isEmpty()) {
671ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // Remove the transparent area from the visible region
672ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (translucent) {
673ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    visibleRegion.subtractSelf(layer->transparentRegionScreen);
674ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
675edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
676ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // compute the opaque region
677ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                const int32_t layerOrientation = layer->getOrientation();
678ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (s.alpha==255 && !translucent &&
679ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                        ((layerOrientation & Transform::ROT_INVALID) == false)) {
680ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    // the opaque region is the layer's footprint
681ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    opaqueRegion = visibleRegion;
682ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
683edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
684edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
685edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
686ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Clip the covered region to the visible region
687ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        coveredRegion = aboveCoveredLayers.intersect(visibleRegion);
688ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
689ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveCoveredLayers for next (lower) layer
690ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        aboveCoveredLayers.orSelf(visibleRegion);
691ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
692edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // subtract the opaque region covered by the layers above us
693edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        visibleRegion.subtractSelf(aboveOpaqueLayers);
694edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
695edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // compute this layer's dirty region
696edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (layer->contentDirty) {
697edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // we need to invalidate the whole region
698edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dirty = visibleRegion;
699edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // as well, as the old visible region
700edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dirty.orSelf(layer->visibleRegionScreen);
701edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->contentDirty = false;
702edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
703a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian            /* compute the exposed region:
704ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   the exposed region consists of two components:
705ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   1) what's VISIBLE now and was COVERED before
706ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   2) what's EXPOSED now less what was EXPOSED before
707ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
708ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * note that (1) is conservative, we start with the whole
709ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * visible region but only keep what used to be covered by
710ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * something -- which mean it may have been exposed.
711ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
712ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * (2) handles areas that were not covered by anything but got
713ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * exposed because of a resize.
714a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian             */
715ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region newExposed = visibleRegion - coveredRegion;
716ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldVisibleRegion = layer->visibleRegionScreen;
717ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldCoveredRegion = layer->coveredRegionScreen;
718ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldExposed = oldVisibleRegion - oldCoveredRegion;
719ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed);
720edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
721edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirty.subtractSelf(aboveOpaqueLayers);
722edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
723edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // accumulate to the screen dirty region
724edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirtyRegion.orSelf(dirty);
725edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
726ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveOpaqueLayers for next (lower) layer
727edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        aboveOpaqueLayers.orSelf(opaqueRegion);
7288b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
729edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // Store the visible region is screen space
730edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setVisibleRegion(visibleRegion);
731edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setCoveredRegion(coveredRegion);
732edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
733970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian        // If a secure layer is partially visible, lock-down the screen!
734edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (layer->isSecure() && !visibleRegion.isEmpty()) {
735edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            secureFrameBuffer = true;
736edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
737edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
738edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
739970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian    // invalidate the areas where a layer was removed
740970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian    dirtyRegion.orSelf(mDirtyRegionRemovedLayer);
741970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian    mDirtyRegionRemovedLayer.clear();
742970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian
743edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mSecureFrameBuffer = secureFrameBuffer;
744edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    opaqueRegion = aboveOpaqueLayers;
745edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
746edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
747edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
748edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::commitTransaction()
749edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
750edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDrawingState = mCurrentState;
75128378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    mTransationPending = false;
752cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mTransactionCV.broadcast();
753edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
754edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
755edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handlePageFlip()
756edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
757edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    bool visibleRegions = mVisibleRegionsDirty;
7581bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian    const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
759edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    visibleRegions |= lockPageFlip(currentLayers);
760edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
761edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const DisplayHardware& hw = graphicPlane(0).displayHardware();
762edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const Region screenRegion(hw.bounds());
763edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (visibleRegions) {
764edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            Region opaqueRegion;
765edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            computeVisibleRegions(currentLayers, mDirtyRegion, opaqueRegion);
7664da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
7674da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            /*
7684da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian             *  rebuild the visible layer list
7694da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian             */
7701bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian            const size_t count = currentLayers.size();
7714da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            mVisibleLayersSortedByZ.clear();
7724da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            mVisibleLayersSortedByZ.setCapacity(count);
7734da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            for (size_t i=0 ; i<count ; i++) {
7744da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian                if (!currentLayers[i]->visibleRegionScreen.isEmpty())
7754da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian                    mVisibleLayersSortedByZ.add(currentLayers[i]);
7764da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            }
7774da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
778edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mWormholeRegion = screenRegion.subtract(opaqueRegion);
779edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = false;
780ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian            invalidateHwcGeometry();
781edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
782edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
783edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    unlockPageFlip(currentLayers);
784edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDirtyRegion.andSelf(screenRegion);
785edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
786edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
787ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopianvoid SurfaceFlinger::invalidateHwcGeometry()
788ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian{
789ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian    mHwWorkListDirty = true;
790ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian}
791ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian
792edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool SurfaceFlinger::lockPageFlip(const LayerVector& currentLayers)
793edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
794edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    bool recomputeVisibleRegions = false;
795edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t count = currentLayers.size();
796076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBase> const* layers = currentLayers.array();
797edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (size_t i=0 ; i<count ; i++) {
798b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
799edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->lockPageFlip(recomputeVisibleRegions);
800edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
801edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return recomputeVisibleRegions;
802edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
803edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
804edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::unlockPageFlip(const LayerVector& currentLayers)
805edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
806edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(graphicPlane(0));
807edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Transform& planeTransform(plane.transform());
808edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t count = currentLayers.size();
809076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBase> const* layers = currentLayers.array();
810edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (size_t i=0 ; i<count ; i++) {
811b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
812edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->unlockPageFlip(planeTransform, mDirtyRegion);
813edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
814edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
815edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
816a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopianvoid SurfaceFlinger::handleWorkList()
817a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian{
818a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    mHwWorkListDirty = false;
819a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    HWComposer& hwc(graphicPlane(0).displayHardware().getHwComposer());
820a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    if (hwc.initCheck() == NO_ERROR) {
821a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        const Vector< sp<LayerBase> >& currentLayers(mVisibleLayersSortedByZ);
822a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        const size_t count = currentLayers.size();
823a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        hwc.createWorkList(count);
82445721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        hwc_layer_t* const cur(hwc.getLayers());
82545721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        for (size_t i=0 ; cur && i<count ; i++) {
82645721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            currentLayers[i]->setGeometry(&cur[i]);
82753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian            if (mDebugDisableHWC || mDebugRegion) {
82873d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian                cur[i].compositionType = HWC_FRAMEBUFFER;
82973d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian                cur[i].flags |= HWC_SKIP_LAYER;
83073d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian            }
831a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        }
832a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
833a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian}
834b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian
835edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleRepaint()
836edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
837b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // compute the invalid region
8380656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian    mSwapRegion.orSelf(mDirtyRegion);
839edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
840edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(mDebugRegion)) {
841edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        debugFlashRegions();
842edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
843edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
844b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // set the frame buffer
845b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
846b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    glMatrixMode(GL_MODELVIEW);
847b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    glLoadIdentity();
848edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
849edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t flags = hw.getFlags();
8508b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber    if ((flags & DisplayHardware::SWAP_RECTANGLE) ||
8518b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber        (flags & DisplayHardware::BUFFER_PRESERVED))
852df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian    {
85329d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // we can redraw only what's dirty, but since SWAP_RECTANGLE only
85429d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // takes a rectangle, we must make sure to update that whole
85529d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // rectangle in that case
85629d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        if (flags & DisplayHardware::SWAP_RECTANGLE) {
857b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            // TODO: we really should be able to pass a region to
85829d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // SWAP_RECTANGLE so that we don't have to redraw all this.
8590656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian            mDirtyRegion.set(mSwapRegion.bounds());
86029d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        } else {
86129d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // in the BUFFER_PRESERVED case, obviously, we can update only
86229d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // what's needed and nothing more.
86329d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // NOTE: this is NOT a common case, as preserving the backbuffer
86429d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // is costly and usually involves copying the whole update back.
86529d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        }
866edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
86795a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian        if (flags & DisplayHardware::PARTIAL_UPDATES) {
86829d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // We need to redraw the rectangle that will be updated
869df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian            // (pushed to the framebuffer).
87095a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian            // This is needed because PARTIAL_UPDATES only takes one
87129d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // rectangle instead of a region (see DisplayHardware::flip())
8720656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian            mDirtyRegion.set(mSwapRegion.bounds());
873edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
87429d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // we need to redraw everything (the whole screen)
875edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mDirtyRegion.set(hw.bounds());
8760656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian            mSwapRegion = mDirtyRegion;
877edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
878edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
879edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
8809c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    setupHardwareComposer(mDirtyRegion);
881edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    composeSurfaces(mDirtyRegion);
882edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
8839c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    // update the swap region and clear the dirty region
8849c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    mSwapRegion.orSelf(mDirtyRegion);
885edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDirtyRegion.clear();
886edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
887edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
8889c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopianvoid SurfaceFlinger::setupHardwareComposer(Region& dirtyInOut)
889edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
890f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
891f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    HWComposer& hwc(hw.getHwComposer());
892f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    hwc_layer_t* const cur(hwc.getLayers());
893f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    if (!cur) {
8949c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        return;
895edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
896a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
8974da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian    const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
89845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    size_t count = layers.size();
899a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
900f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    LOGE_IF(hwc.getNumLayers() != count,
90145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            "HAL number of layers (%d) doesn't match surfaceflinger (%d)",
90245721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            hwc.getNumLayers(), count);
903a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
90445721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    // just to be extra-safe, use the smallest count
90524925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling    if (hwc.initCheck() == NO_ERROR) {
90624925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling        count = count < hwc.getNumLayers() ? count : hwc.getNumLayers();
90724925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling    }
908a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
90945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    /*
91045721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     *  update the per-frame h/w composer data for each layer
91145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     *  and build the transparent region of the FB
91245721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     */
913f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
914f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
915f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        layer->setPerFrameData(&cur[i]);
916f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    }
9179c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    const size_t fbLayerCount = hwc.getLayerCount(HWC_FRAMEBUFFER);
918f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    status_t err = hwc.prepare();
919f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    LOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
920f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian
921f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    if (err == NO_ERROR) {
9229c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // what's happening here is tricky.
9239c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // we want to clear all the layers with the CLEAR_FB flags
9249c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // that are opaque.
9259c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // however, since some GPU are efficient at preserving
9269c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // the backbuffer, we want to take advantage of that so we do the
9279c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // clear only in the dirty region (other areas will be preserved
9289c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // on those GPUs).
9299c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        //   NOTE: on non backbuffer preserving GPU, the dirty region
9309c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        //   has already been expanded as needed, so the code is correct
9319c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        //   there too.
9329c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        //
9339c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // However, the content of the framebuffer cannot be trusted when
9349c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // we switch to/from FB/OVERLAY, in which case we need to
9359c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // expand the dirty region to those areas too.
9369c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        //
9379c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // Note also that there is a special case when switching from
9389c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // "no layers in FB" to "some layers in FB", where we need to redraw
9399c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // the entire FB, since some areas might contain uninitialized
9409c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // data.
9419c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        //
9429c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // Also we want to make sure to not clear areas that belong to
9439c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // layers above that won't redraw (we would just erasing them),
9449c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // that is, we can't erase anything outside the dirty region.
945a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
9469c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        Region transparent;
947f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian
9489c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        if (!fbLayerCount && hwc.getLayerCount(HWC_FRAMEBUFFER)) {
9499c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian            transparent.set(hw.getBounds());
9509c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian            dirtyInOut = transparent;
9519c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        } else {
9529c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian            for (size_t i=0 ; i<count ; i++) {
9539c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                const sp<LayerBase>& layer(layers[i]);
9549c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                if ((cur[i].hints & HWC_HINT_CLEAR_FB) && layer->isOpaque()) {
9559c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                    transparent.orSelf(layer->visibleRegionScreen);
9569c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                }
9579c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                bool isOverlay = (cur[i].compositionType != HWC_FRAMEBUFFER);
9589c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                if (isOverlay != layer->isOverlay()) {
9599c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                    // we transitioned to/from overlay, so add this layer
9609c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                    // to the dirty region so the framebuffer can be either
9619c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                    // cleared or redrawn.
9629c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                    dirtyInOut.orSelf(layer->visibleRegionScreen);
9639c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                }
9649c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                layer->setOverlay(isOverlay);
965f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian            }
9669c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian            // don't erase stuff outside the dirty region
9679c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian            transparent.andSelf(dirtyInOut);
968f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        }
969f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian
970f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        /*
971f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian         *  clear the area of the FB that need to be transparent
972f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian         */
973f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        if (!transparent.isEmpty()) {
974f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian            glClearColor(0,0,0,0);
975f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian            Region::const_iterator it = transparent.begin();
976f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian            Region::const_iterator const end = transparent.end();
977f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian            const int32_t height = hw.getHeight();
978f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian            while (it != end) {
979f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian                const Rect& r(*it++);
980f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian                const GLint sy = height - (r.top + r.height());
981f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian                glScissor(r.left, sy, r.width(), r.height());
982f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian                glClear(GL_COLOR_BUFFER_BIT);
983f20a32415d055336bc6016fa2de36d126db32746Mathias Agopian            }
984a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        }
985a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
986f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian}
987f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian
988f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopianvoid SurfaceFlinger::composeSurfaces(const Region& dirty)
989f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian{
990cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
991cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian    HWComposer& hwc(hw.getHwComposer());
992cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian
993cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian    const size_t fbLayerCount = hwc.getLayerCount(HWC_FRAMEBUFFER);
994cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian    if (UNLIKELY(fbLayerCount && !mWormholeRegion.isEmpty())) {
995f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        // should never happen unless the window manager has a bug
996f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        // draw something...
997f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        drawWormhole();
998f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    }
99945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian
100045721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    /*
100145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     * and then, render the layers targeted at the framebuffer
100245721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     */
1003cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian    hwc_layer_t* const cur(hwc.getLayers());
1004f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
1005f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    size_t count = layers.size();
100645721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
10079c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        if (cur && (cur[i].compositionType != HWC_FRAMEBUFFER)) {
1008f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian            continue;
100945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        }
101045721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
101145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        const Region clip(dirty.intersect(layer->visibleRegionScreen));
101245721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        if (!clip.isEmpty()) {
101345721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            layer->draw(clip);
101445721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        }
101545721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    }
1016edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1017edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1018edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::debugFlashRegions()
1019edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
10200a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
10210a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    const uint32_t flags = hw.getFlags();
102253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian    const int32_t height = hw.getHeight();
10230656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian    if (mSwapRegion.isEmpty()) {
102453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian        return;
102553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian    }
10260a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
10270a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    if (!((flags & DisplayHardware::SWAP_RECTANGLE) ||
10280a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian            (flags & DisplayHardware::BUFFER_PRESERVED))) {
10290a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        const Region repaint((flags & DisplayHardware::PARTIAL_UPDATES) ?
10300a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian                mDirtyRegion.bounds() : hw.bounds());
10310a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        composeSurfaces(repaint);
10320a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    }
10330a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
1034edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_BLEND);
1035edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_DITHER);
1036edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_SCISSOR_TEST);
1037edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
10380926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    static int toggle = 0;
10390926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    toggle = 1 - toggle;
10400926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    if (toggle) {
10410a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        glColor4f(1, 0, 1, 1);
10420926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    } else {
10430a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        glColor4f(1, 1, 0, 1);
10440926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    }
1045edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
104620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    Region::const_iterator it = mDirtyRegion.begin();
104720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    Region::const_iterator const end = mDirtyRegion.end();
104820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    while (it != end) {
104920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        const Rect& r = *it++;
1050edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLfloat vertices[][2] = {
105153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.left,  height - r.top },
105253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.left,  height - r.bottom },
105353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.right, height - r.bottom },
105453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.right, height - r.top }
1055edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        };
1056edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glVertexPointer(2, GL_FLOAT, 0, vertices);
1057edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1058edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
10590a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
10600656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian    hw.flip(mSwapRegion);
1061edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1062edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mDebugRegion > 1)
10630a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        usleep(mDebugRegion * 1000);
1064edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1065edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glEnable(GL_SCISSOR_TEST);
1066edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1067edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1068edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::drawWormhole() const
1069edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1070edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Region region(mWormholeRegion.intersect(mDirtyRegion));
1071edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (region.isEmpty())
1072edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1073edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1074edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw(graphicPlane(0).displayHardware());
1075edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int32_t width = hw.getWidth();
1076edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int32_t height = hw.getHeight();
1077edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1078edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_BLEND);
1079edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_DITHER);
1080edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1081edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (LIKELY(!mDebugBackground)) {
10820a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        glClearColor(0,0,0,0);
108320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        Region::const_iterator it = region.begin();
108420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        Region::const_iterator const end = region.end();
108520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        while (it != end) {
108620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            const Rect& r = *it++;
1087edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const GLint sy = height - (r.top + r.height());
1088edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glScissor(r.left, sy, r.width(), r.height());
1089edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glClear(GL_COLOR_BUFFER_BIT);
1090edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1091edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
1092edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GLshort vertices[][2] = { { 0, 0 }, { width, 0 },
1093edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                { width, height }, { 0, height }  };
1094edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GLshort tcoords[][2] = { { 0, 0 }, { 1, 0 },  { 1, 1 }, { 0, 1 } };
1095edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glVertexPointer(2, GL_SHORT, 0, vertices);
1096edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glTexCoordPointer(2, GL_SHORT, 0, tcoords);
1097edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
10987f198b6bff54af3c8e8ac32b83ffc6488e773ac1Michael I. Gold#if defined(GL_OES_EGL_image_external)
10991f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian        if (GLExtensions::getInstance().haveTextureExternal()) {
11001f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian            glDisable(GL_TEXTURE_EXTERNAL_OES);
11011f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian        }
11020a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian#endif
1103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glEnable(GL_TEXTURE_2D);
1104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glBindTexture(GL_TEXTURE_2D, mWormholeTexName);
1105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glMatrixMode(GL_TEXTURE);
1107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glLoadIdentity();
1108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glScalef(width*(1.0f/32.0f), height*(1.0f/32.0f), 1);
110920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        Region::const_iterator it = region.begin();
111020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        Region::const_iterator const end = region.end();
111120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        while (it != end) {
111220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            const Rect& r = *it++;
1113edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const GLint sy = height - (r.top + r.height());
1114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glScissor(r.left, sy, r.width(), r.height());
1115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1118a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        glDisable(GL_TEXTURE_2D);
1119ebeb7095961e09f5cff0c7cf2c04fa4770b2e033Mathias Agopian        glLoadIdentity();
1120ebeb7095961e09f5cff0c7cf2c04fa4770b2e033Mathias Agopian        glMatrixMode(GL_MODELVIEW);
1121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::debugShowFPS() const
1125edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1126edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    static int mFrameCount;
1127edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    static int mLastFrameCount = 0;
1128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    static nsecs_t mLastFpsTime = 0;
1129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    static float mFps = 0;
1130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mFrameCount++;
1131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    nsecs_t now = systemTime();
1132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    nsecs_t diff = now - mLastFpsTime;
1133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (diff > ms2ns(250)) {
1134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mFps =  ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff;
1135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mLastFpsTime = now;
1136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mLastFrameCount = mFrameCount;
1137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // XXX: mFPS has the value we want
1139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project }
1140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1141076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::addLayer(const sp<LayerBase>& layer)
1142edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1143edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
1144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    addLayer_l(layer);
1145edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
1146edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1147edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1148edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1149076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::addLayer_l(const sp<LayerBase>& layer)
1150edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1151f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian    ssize_t i = mCurrentState.layersSortedByZ.add(layer);
11521b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    return (i < 0) ? status_t(i) : status_t(NO_ERROR);
11531b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian}
11541b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
115596f0819f81293076e652792794a961543e6750d7Mathias Agopianssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
115696f0819f81293076e652792794a961543e6750d7Mathias Agopian        const sp<LayerBaseClient>& lbc)
11571b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
115896f0819f81293076e652792794a961543e6750d7Mathias Agopian    // attach this layer to the client
11594f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    size_t name = client->attachLayer(lbc);
11604f113740180b6512b43723c4728f262882dc9b45Mathias Agopian
11614f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    Mutex::Autolock _l(mStateLock);
116296f0819f81293076e652792794a961543e6750d7Mathias Agopian
116396f0819f81293076e652792794a961543e6750d7Mathias Agopian    // add this layer to the current state list
116496f0819f81293076e652792794a961543e6750d7Mathias Agopian    addLayer_l(lbc);
116596f0819f81293076e652792794a961543e6750d7Mathias Agopian
11664f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    return ssize_t(name);
116796f0819f81293076e652792794a961543e6750d7Mathias Agopian}
116896f0819f81293076e652792794a961543e6750d7Mathias Agopian
116996f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer)
117096f0819f81293076e652792794a961543e6750d7Mathias Agopian{
117196f0819f81293076e652792794a961543e6750d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
117296f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = purgatorizeLayer_l(layer);
117396f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR)
117496f0819f81293076e652792794a961543e6750d7Mathias Agopian        setTransactionFlags(eTransactionNeeded);
117596f0819f81293076e652792794a961543e6750d7Mathias Agopian    return err;
1176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1178076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase)
1179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1180b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<LayerBaseClient> lbc(layerBase->getLayerBaseClient());
1181b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (lbc != 0) {
11820d1561275e80073807ac04728951782d943f8882Mathias Agopian        mLayerMap.removeItem( lbc->getSurfaceBinder() );
1183b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    }
1184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase);
1185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (index >= 0) {
1186076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved = true;
1187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
1188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
11893d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    return status_t(index);
1190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
11929a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase)
11939a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
119476cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    // First add the layer to the purgatory list, which makes sure it won't
119576cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    // go away, then remove it from the main list (through a transaction).
11969a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    ssize_t err = removeLayer_l(layerBase);
119776cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    if (err >= 0) {
119876cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian        mLayerPurgatory.add(layerBase);
119976cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    }
12008c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian
12010b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian    layerBase->onRemoved();
12020b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian
12033d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // it's possible that we don't find a layer, because it might
12043d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // have been destroyed already -- this is not technically an error
120596f0819f81293076e652792794a961543e6750d7Mathias Agopian    // from the user because there is a race between Client::destroySurface(),
120696f0819f81293076e652792794a961543e6750d7Mathias Agopian    // ~Client() and ~ISurface().
12079a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err;
12089a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
12099a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
121096f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::invalidateLayerVisibility(const sp<LayerBase>& layer)
1211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
121296f0819f81293076e652792794a961543e6750d7Mathias Agopian    layer->forceVisibilityTransaction();
121396f0819f81293076e652792794a961543e6750d7Mathias Agopian    setTransactionFlags(eTraversalNeeded);
121496f0819f81293076e652792794a961543e6750d7Mathias Agopian    return NO_ERROR;
1215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1217dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopianuint32_t SurfaceFlinger::peekTransactionFlags(uint32_t flags)
1218dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian{
1219dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian    return android_atomic_release_load(&mTransactionFlags);
1220dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian}
1221dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian
1222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags)
1223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return android_atomic_and(~flags, &mTransactionFlags) & flags;
1225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1227bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags)
1228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t old = android_atomic_or(flags, &mTransactionFlags);
1230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((old & flags)==0) { // wake the server up
1231bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        signalEvent();
1232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1233edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return old;
1234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1237b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennisvoid SurfaceFlinger::setTransactionState(const Vector<ComposerState>& state,
123828378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        int orientation, uint32_t flags) {
1239698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
1240cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
124128378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    uint32_t transactionFlags = 0;
1242b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis    if (mCurrentState.orientation != orientation) {
1243b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis        if (uint32_t(orientation)<=eOrientation270 || orientation==42) {
1244b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis            mCurrentState.orientation = orientation;
124528378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis            transactionFlags |= eTransactionNeeded;
1246b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis        } else if (orientation != eOrientationUnchanged) {
1247b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis            LOGW("setTransactionState: ignoring unrecognized orientation: %d",
1248b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis                    orientation);
1249b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis        }
1250b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis    }
1251b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis
1252698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    const size_t count = state.size();
1253698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
1254698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const ComposerState& s(state[i]);
1255698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        sp<Client> client( static_cast<Client *>(s.client.get()) );
125628378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        transactionFlags |= setClientStateLocked(client, s.state);
1257698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    }
125828378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    if (transactionFlags) {
125928378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        setTransactionFlags(transactionFlags);
1260698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    }
1261698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian
126228378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    // if this is a synchronous transaction, wait for it to take effect before
126328378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    // returning.
126428378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    if (flags & eSynchronous) {
126528378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        mTransationPending = true;
126628378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    }
126728378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    while (mTransationPending) {
1268698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
1269698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (CC_UNLIKELY(err != NO_ERROR)) {
1270698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            // just in case something goes wrong in SF, return to the
1271698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            // called after a few seconds.
1272698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            LOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!");
127328378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis            mTransationPending = false;
1274698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            break;
1275cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        }
1276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1278edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::freezeDisplay(DisplayID dpy, uint32_t flags)
1280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
1282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return BAD_VALUE;
1283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1284edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
1285edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mCurrentState.freezeDisplay = 1;
1286edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    setTransactionFlags(eTransactionNeeded);
1287edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1288edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // flags is intended to communicate some sort of animation behavior
128962b74444be6742ab6b877918c85caeb9f2f1a2c9Mathias Agopian    // (for instance fading)
1290edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1291edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1292edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1293edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::unfreezeDisplay(DisplayID dpy, uint32_t flags)
1294edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1295edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
1296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return BAD_VALUE;
1297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
1299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mCurrentState.freezeDisplay = 0;
1300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    setTransactionFlags(eTransactionNeeded);
1301edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1302edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // flags is intended to communicate some sort of animation behavior
130362b74444be6742ab6b877918c85caeb9f2f1a2c9Mathias Agopian    // (for instance fading)
1304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
13078b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huberint SurfaceFlinger::setOrientation(DisplayID dpy,
1308c08731e756868653d09d3e49b723706df3687070Mathias Agopian        int orientation, uint32_t flags)
1309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1310edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
1311edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return BAD_VALUE;
1312edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1313edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
1314edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mCurrentState.orientation != orientation) {
1315edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (uint32_t(orientation)<=eOrientation270 || orientation==42) {
131621230c6410bdab13cd2bd274da54b1e4061b6035Jeff Brown            mCurrentState.orientationFlags = flags;
1317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mCurrentState.orientation = orientation;
1318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            setTransactionFlags(eTransactionNeeded);
1319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mTransactionCV.wait(mStateLock);
1320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
1321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            orientation = BAD_VALUE;
1322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1323edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1324edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return orientation;
1325edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1326edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
13270ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopiansp<ISurface> SurfaceFlinger::createSurface(
13280ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        ISurfaceComposerClient::surface_data_t* params,
13290ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const String8& name,
13300ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const sp<Client>& client,
1331edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        DisplayID d, uint32_t w, uint32_t h, PixelFormat format,
1332edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t flags)
1333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1334076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBaseClient> layer;
1335a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    sp<ISurface> surfaceHandle;
13366e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian
13376e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    if (int32_t(w|h) < 0) {
13386e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian        LOGE("createSurface() failed, w or h is negative (w=%d, h=%d)",
13396e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian                int(w), int(h));
13406e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian        return surfaceHandle;
13416e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    }
13428b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
1343edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    //LOGD("createSurface for pid %d (%d x %d)", pid, w, h);
1344b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<Layer> normalLayer;
1345edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (flags & eFXSurfaceMask) {
1346edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceNormal:
1347a5529c8778c2f407f482fc12165aeb76c0f505c2Mathias Agopian            normalLayer = createNormalSurface(client, d, w, h, flags, format);
1348a5529c8778c2f407f482fc12165aeb76c0f505c2Mathias Agopian            layer = normalLayer;
1349edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
1350edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceBlur:
13511293a8eb567fd63c072a6970fa9dcf37d076059fMathias Agopian            // for now we treat Blur as Dim, until we can implement it
13521293a8eb567fd63c072a6970fa9dcf37d076059fMathias Agopian            // efficiently.
1353edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceDim:
135496f0819f81293076e652792794a961543e6750d7Mathias Agopian            layer = createDimSurface(client, d, w, h, flags);
1355edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
1356edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1357edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1358076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (layer != 0) {
135996f0819f81293076e652792794a961543e6750d7Mathias Agopian        layer->initStates(w, h, flags);
1360285dbde2e0cd0057be070ded3be8f5f453147edcMathias Agopian        layer->setName(name);
136196f0819f81293076e652792794a961543e6750d7Mathias Agopian        ssize_t token = addClientLayer(client, layer);
1362b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1363edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        surfaceHandle = layer->getSurface();
13648b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber        if (surfaceHandle != 0) {
136596f0819f81293076e652792794a961543e6750d7Mathias Agopian            params->token = token;
1366a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            params->identity = layer->getIdentity();
1367b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            if (normalLayer != 0) {
1368b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian                Mutex::Autolock _l(mStateLock);
1369a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                mLayerMap.add(layer->getSurfaceBinder(), normalLayer);
1370b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            }
13711c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        }
1372b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
137396f0819f81293076e652792794a961543e6750d7Mathias Agopian        setTransactionFlags(eTransactionNeeded);
1374edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1375edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1376edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return surfaceHandle;
1377edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1378edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1379b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<Layer> SurfaceFlinger::createNormalSurface(
1380f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        const sp<Client>& client, DisplayID display,
138196f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags,
13821c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        PixelFormat& format)
1383edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1384edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize the surfaces
1385edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (format) { // TODO: take h/w into account
1386edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSPARENT:
1387edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSLUCENT:
1388edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        format = PIXEL_FORMAT_RGBA_8888;
1389edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1390edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_OPAQUE:
1391a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888
1392a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian        format = PIXEL_FORMAT_RGB_565;
1393a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#else
13948f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian        format = PIXEL_FORMAT_RGBX_8888;
1395a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif
1396edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1397edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1398edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1399a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888
1400a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian    if (format == PIXEL_FORMAT_RGBX_8888)
1401a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian        format = PIXEL_FORMAT_RGBA_8888;
1402a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif
1403a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian
140496f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<Layer> layer = new Layer(this, display, client);
1405f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian    status_t err = layer->setBuffers(w, h, format, flags);
140696f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (LIKELY(err != NO_ERROR)) {
1407edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        LOGE("createNormalSurfaceLocked() failed (%s)", strerror(-err));
1408076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        layer.clear();
1409edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1410edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1411edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1412edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1413b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<LayerDim> SurfaceFlinger::createDimSurface(
1414f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        const sp<Client>& client, DisplayID display,
141596f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags)
1416edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
141796f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<LayerDim> layer = new LayerDim(this, display, client);
1418edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    layer->initStates(w, h, flags);
1419edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1420edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1421edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
142296f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeSurface(const sp<Client>& client, SurfaceID sid)
14239a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
14249a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    /*
14259a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     * called by the window manager, when a surface should be marked for
14269a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     * destruction.
14278b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber     *
14280aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * The surface is removed from the current and drawing lists, but placed
14290aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * in the purgatory queue, so it's not destroyed right-away (we need
14300aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * to wait for all client's references to go away first).
14319a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     */
14329a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
143348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    status_t err = NAME_NOT_FOUND;
14340aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian    Mutex::Autolock _l(mStateLock);
143596f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<LayerBaseClient> layer = client->getLayerUser(sid);
143648d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    if (layer != 0) {
143748d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        err = purgatorizeLayer_l(layer);
143848d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        if (err == NO_ERROR) {
143948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian            setTransactionFlags(eTransactionNeeded);
144048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        }
14419a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    }
14429a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return err;
14439a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
14449a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
1445ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopianstatus_t SurfaceFlinger::destroySurface(const wp<LayerBaseClient>& layer)
1446edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1447759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian    // called by ~ISurface() when all references are gone
1448ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    status_t err = NO_ERROR;
1449ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    sp<LayerBaseClient> l(layer.promote());
1450ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    if (l != NULL) {
1451ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        Mutex::Autolock _l(mStateLock);
1452ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        err = removeLayer_l(l);
1453ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        if (err == NAME_NOT_FOUND) {
1454ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // The surface wasn't in the current list, which means it was
1455ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // removed already, which means it is in the purgatory,
1456ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // and need to be removed from there.
1457ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            ssize_t idx = mLayerPurgatory.remove(l);
1458ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            LOGE_IF(idx < 0,
1459ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian                    "layer=%p is not in the purgatory list", l.get());
1460f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        }
1461ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        LOGE_IF(err<0 && err != NAME_NOT_FOUND,
1462ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian                "error removing layer=%p (%s)", l.get(), strerror(-err));
1463ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    }
1464ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    return err;
1465edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1466edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1467698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopianuint32_t SurfaceFlinger::setClientStateLocked(
146896f0819f81293076e652792794a961543e6750d7Mathias Agopian        const sp<Client>& client,
1469698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const layer_state_t& s)
1470edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1471edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t flags = 0;
1472698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    sp<LayerBaseClient> layer(client->getLayerUser(s.surface));
1473698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    if (layer != 0) {
1474698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const uint32_t what = s.what;
1475698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & ePositionChanged) {
1476698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setPosition(s.x, s.y))
1477698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1478698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1479698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eLayerChanged) {
1480698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
1481698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setLayer(s.z)) {
1482698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                mCurrentState.layersSortedByZ.removeAt(idx);
1483698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                mCurrentState.layersSortedByZ.add(layer);
1484698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                // we need traversal (state changed)
1485698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                // AND transaction (list changed)
1486698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTransactionNeeded|eTraversalNeeded;
1487edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1488698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1489698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eSizeChanged) {
1490698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setSize(s.w, s.h)) {
1491698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1492edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1493edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1494698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eAlphaChanged) {
1495698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f)))
1496698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1497698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1498698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eMatrixChanged) {
1499698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setMatrix(s.matrix))
1500698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1501698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1502698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eTransparentRegionChanged) {
1503698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setTransparentRegionHint(s.transparentRegion))
1504698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1505698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1506698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eVisibilityChanged) {
1507698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setFlags(s.flags, s.mask))
1508698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1509698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1510edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1511698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    return flags;
1512edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1513edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1514edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::screenReleased(int dpy)
1515edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1516edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // this may be called by a signal handler, we can't do too much in here
1517edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    android_atomic_or(eConsoleReleased, &mConsoleSignals);
1518edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    signalEvent();
1519edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1520edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1521edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::screenAcquired(int dpy)
1522edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1523edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // this may be called by a signal handler, we can't do too much in here
1524edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    android_atomic_or(eConsoleAcquired, &mConsoleSignals);
1525edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    signalEvent();
1526edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1527edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1528edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
1529edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
15301d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling    const size_t SIZE = 4096;
1531edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char buffer[SIZE];
1532edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    String8 result;
153399b49840d309727678b77403d6cc9f920111623fMathias Agopian
153499b49840d309727678b77403d6cc9f920111623fMathias Agopian    if (!PermissionCache::checkCallingPermission(sDump)) {
1535edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        snprintf(buffer, SIZE, "Permission Denial: "
1536edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                "can't dump SurfaceFlinger from pid=%d, uid=%d\n",
1537edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                IPCThreadState::self()->getCallingPid(),
1538edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                IPCThreadState::self()->getCallingUid());
1539edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        result.append(buffer);
1540edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
15419795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
15429795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // figure out if we're stuck somewhere
15439795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const nsecs_t now = systemTime();
15449795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const nsecs_t inSwapBuffers(mDebugInSwapBuffers);
15459795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const nsecs_t inTransaction(mDebugInTransaction);
15469795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0;
15479795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0;
15489795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
15499795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // Try to get the main lock, but don't insist if we can't
15509795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // (this would indicate SF is stuck, but we want to be able to
15519795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // print something in dumpsys).
15529795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        int retry = 3;
15539795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        while (mStateLock.tryLock()<0 && --retry>=0) {
15549795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            usleep(1000000);
15559795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
15569795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const bool locked(retry >= 0);
15579795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (!locked) {
15588b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber            snprintf(buffer, SIZE,
15599795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "SurfaceFlinger appears to be unresponsive, "
15609795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "dumping anyways (no locks held)\n");
15619795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            result.append(buffer);
15629795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
15639795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
156448b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        /*
156548b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian         * Dump the visible layer list
156648b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian         */
1567edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
1568edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const size_t count = currentLayers.size();
156948b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        snprintf(buffer, SIZE, "Visible layers (count = %d)\n", count);
157048b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        result.append(buffer);
1571edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (size_t i=0 ; i<count ; i++) {
15721b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            const sp<LayerBase>& layer(currentLayers[i]);
15731b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            layer->dump(result, buffer, SIZE);
15741b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            const Layer::State& s(layer->drawingState());
1575edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            s.transparentRegion.dump(result, "transparentRegion");
1576edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->transparentRegionScreen.dump(result, "transparentRegionScreen");
1577edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->visibleRegionScreen.dump(result, "visibleRegionScreen");
1578edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
15791b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
158048b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        /*
158148b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian         * Dump the layers in the purgatory
158248b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian         */
158348b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
158448b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        const size_t purgatorySize =  mLayerPurgatory.size();
158548b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        snprintf(buffer, SIZE, "Purgatory state (%d entries)\n", purgatorySize);
158648b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        result.append(buffer);
158748b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        for (size_t i=0 ; i<purgatorySize ; i++) {
158848b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian            const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
158948b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian            layer->shortDump(result, buffer, SIZE);
159048b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        }
159148b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
159248b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        /*
159348b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian         * Dump SurfaceFlinger global state
159448b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian         */
159548b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
1596ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian        snprintf(buffer, SIZE, "SurfaceFlinger global state:\n");
159748b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        result.append(buffer);
1598ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian
1599ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian        const GLExtensions& extensions(GLExtensions::getInstance());
1600ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian        snprintf(buffer, SIZE, "GLES: %s, %s, %s\n",
1601ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian                extensions.getVendor(),
1602ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian                extensions.getRenderer(),
1603ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian                extensions.getVersion());
1604ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian        result.append(buffer);
1605ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian        snprintf(buffer, SIZE, "EXTS: %s\n", extensions.getExtension());
1606ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian        result.append(buffer);
1607ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian
1608edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mWormholeRegion.dump(result, "WormholeRegion");
1609edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const DisplayHardware& hw(graphicPlane(0).displayHardware());
1610edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        snprintf(buffer, SIZE,
1611edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                "  display frozen: %s, freezeCount=%d, orientation=%d, canDraw=%d\n",
1612edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mFreezeDisplay?"yes":"no", mFreezeCount,
1613edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mCurrentState.orientation, hw.canDraw());
1614edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        result.append(buffer);
16159795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        snprintf(buffer, SIZE,
16169795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                "  last eglSwapBuffers() time: %f us\n"
16179795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                "  last transaction time     : %f us\n",
16189795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                mLastSwapBufferTime/1000.0, mLastTransactionTime/1000.0);
16199795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        result.append(buffer);
16201b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
16219795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (inSwapBuffersDuration || !locked) {
16229795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            snprintf(buffer, SIZE, "  eglSwapBuffers time: %f us\n",
16239795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    inSwapBuffersDuration/1000.0);
16249795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            result.append(buffer);
16259795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
16261b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
16279795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (inTransactionDuration || !locked) {
16289795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            snprintf(buffer, SIZE, "  transaction time: %f us\n",
16299795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    inTransactionDuration/1000.0);
16309795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            result.append(buffer);
16319795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
16321b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
163348b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        /*
163448b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian         * Dump HWComposer state
163548b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian         */
163673d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian        HWComposer& hwc(hw.getHwComposer());
163773d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian        snprintf(buffer, SIZE, "  h/w composer %s and %s\n",
163873d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian                hwc.initCheck()==NO_ERROR ? "present" : "not present",
163953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                (mDebugDisableHWC || mDebugRegion) ? "disabled" : "enabled");
164073d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian        result.append(buffer);
164122da60c3e64cd57535cbba063c07127814a2b52fMathias Agopian        hwc.dump(result, buffer, SIZE, mVisibleLayersSortedByZ);
164273d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian
164348b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        /*
164448b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian         * Dump gralloc state
164548b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian         */
16463330b203039dea366d4981db1408a460134b2d2cMathias Agopian        const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
1647076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        alloc.dump(result);
16481d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling        hw.dump(result);
16499795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
16509795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (locked) {
16519795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            mStateLock.unlock();
16529795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
1653edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1654edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    write(fd, result.string(), result.size());
1655edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1656edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1657edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1658edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::onTransact(
1659edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
1660edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1661edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (code) {
1662edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case CREATE_CONNECTION:
1663698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        case SET_TRANSACTION_STATE:
1664edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case SET_ORIENTATION:
1665edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case FREEZE_DISPLAY:
1666edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case UNFREEZE_DISPLAY:
1667edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case BOOT_FINISHED:
166859119e658a12279e8fff508f8773843de2d90917Mathias Agopian        case TURN_ELECTRON_BEAM_OFF:
16699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        case TURN_ELECTRON_BEAM_ON:
1670edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        {
1671edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // codes that require permission check
1672edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            IPCThreadState* ipc = IPCThreadState::self();
1673edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int pid = ipc->getCallingPid();
1674a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian            const int uid = ipc->getCallingUid();
167599b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
167699b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) {
1677375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                LOGE("Permission Denial: "
1678375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                        "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
1679375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                return PERMISSION_DENIED;
1680edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
16811b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
16821b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
16831b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        case CAPTURE_SCREEN:
16841b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
16851b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            // codes that require permission check
16861b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
16871b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int pid = ipc->getCallingPid();
16881b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int uid = ipc->getCallingUid();
168999b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
169099b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) {
16911b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                LOGE("Permission Denial: "
16921b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                        "can't read framebuffer pid=%d, uid=%d", pid, uid);
16931b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                return PERMISSION_DENIED;
16941b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            }
16951b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
1696edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1697edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
16981b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
1699edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
1700edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
1701b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        CHECK_INTERFACE(ISurfaceComposer, data, reply);
170299b49840d309727678b77403d6cc9f920111623fMathias Agopian        if (UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) {
1703375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
1704375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int pid = ipc->getCallingPid();
1705375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int uid = ipc->getCallingUid();
1706375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            LOGE("Permission Denial: "
1707375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                    "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
1708edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return PERMISSION_DENIED;
1709edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1710edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int n;
1711edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        switch (code) {
171201b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian            case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE
171335b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian            case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE
1714edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1715edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1002:  // SHOW_UPDATES
1716edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                n = data.readInt32();
1717edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDebugRegion = n ? n : (mDebugRegion ? 0 : 1);
171853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
171953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
1720edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1721edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1003:  // SHOW_BACKGROUND
1722edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                n = data.readInt32();
1723edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDebugBackground = n ? 1 : 0;
1724edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1725edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1004:{ // repaint everything
172653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
1727cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
1728cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            }
1729cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            case 1005:{ // force transaction
1730cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
1731cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
1732edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
173335b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian            case 1006:{ // enable/disable GraphicLog
173435b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian                int enabled = data.readInt32();
173535b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian                GraphicLog::getInstance().setEnabled(enabled);
173635b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian                return NO_ERROR;
173735b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian            }
1738edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1007: // set mFreezeCount
1739edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mFreezeCount = data.readInt32();
17400408772e34931351d062f2088b611325ddaa6cdbMathias Agopian                mFreezeDisplayTime = 0;
1741edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
174253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian            case 1008:  // toggle use of hw composer
174353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                n = data.readInt32();
174453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                mDebugDisableHWC = n ? 1 : 0;
174553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
174653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
174753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                return NO_ERROR;
1748a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian            case 1009:  // toggle use of transform hint
1749a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                n = data.readInt32();
1750a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                mDebugDisableTransformHint = n ? 1 : 0;
1751a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                invalidateHwcGeometry();
1752a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                repaintEverything();
1753a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                return NO_ERROR;
1754edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1010:  // interrogate.
175501b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian                reply->writeInt32(0);
1756edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(0);
1757edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(mDebugRegion);
1758edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(mDebugBackground);
1759edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1760edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1013: {
1761edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                Mutex::Autolock _l(mStateLock);
1762edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                const DisplayHardware& hw(graphicPlane(0).displayHardware());
1763edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(hw.getPageFlipCount());
1764edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1765edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return NO_ERROR;
1766edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1767edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1768edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return err;
1769edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1770edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
177153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopianvoid SurfaceFlinger::repaintEverything() {
177253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian    Mutex::Autolock _l(mStateLock);
177353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
177453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian    mDirtyRegion.set(hw.bounds()); // careful that's not thread-safe
177553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian    signalEvent();
177653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian}
177753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian
177859119e658a12279e8fff508f8773843de2d90917Mathias Agopian// ---------------------------------------------------------------------------
177959119e658a12279e8fff508f8773843de2d90917Mathias Agopian
17809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::renderScreenToTextureLocked(DisplayID dpy,
17819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        GLuint* textureName, GLfloat* uOut, GLfloat* vOut)
178259119e658a12279e8fff508f8773843de2d90917Mathias Agopian{
178359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
178459119e658a12279e8fff508f8773843de2d90917Mathias Agopian        return INVALID_OPERATION;
178559119e658a12279e8fff508f8773843de2d90917Mathias Agopian
178659119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // get screen geometry
178759119e658a12279e8fff508f8773843de2d90917Mathias Agopian    const DisplayHardware& hw(graphicPlane(dpy).displayHardware());
178859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    const uint32_t hw_w = hw.getWidth();
178959119e658a12279e8fff508f8773843de2d90917Mathias Agopian    const uint32_t hw_h = hw.getHeight();
179059119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLfloat u = 1;
179159119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLfloat v = 1;
179259119e658a12279e8fff508f8773843de2d90917Mathias Agopian
179359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // make sure to clear all GL error flags
179459119e658a12279e8fff508f8773843de2d90917Mathias Agopian    while ( glGetError() != GL_NO_ERROR ) ;
179559119e658a12279e8fff508f8773843de2d90917Mathias Agopian
179659119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // create a FBO
179759119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLuint name, tname;
179859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glGenTextures(1, &tname);
179959119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
18009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
18019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            hw_w, hw_h, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
180259119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (glGetError() != GL_NO_ERROR) {
1803015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian        while ( glGetError() != GL_NO_ERROR ) ;
180459119e658a12279e8fff508f8773843de2d90917Mathias Agopian        GLint tw = (2 << (31 - clz(hw_w)));
180559119e658a12279e8fff508f8773843de2d90917Mathias Agopian        GLint th = (2 << (31 - clz(hw_h)));
18069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
18079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian                tw, th, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
180859119e658a12279e8fff508f8773843de2d90917Mathias Agopian        u = GLfloat(hw_w) / tw;
180959119e658a12279e8fff508f8773843de2d90917Mathias Agopian        v = GLfloat(hw_h) / th;
181059119e658a12279e8fff508f8773843de2d90917Mathias Agopian    }
181159119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glGenFramebuffersOES(1, &name);
181259119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
18139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES,
18149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0);
181559119e658a12279e8fff508f8773843de2d90917Mathias Agopian
18169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // redraw the screen entirely...
18179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glClearColor(0,0,0,1);
18189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glClear(GL_COLOR_BUFFER_BIT);
1819a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glMatrixMode(GL_MODELVIEW);
1820a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glLoadIdentity();
18219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
18229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const size_t count = layers.size();
18239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (size_t i=0 ; i<count ; ++i) {
18249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
18259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        layer->drawForSreenShot();
18269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
182759119e658a12279e8fff508f8773843de2d90917Mathias Agopian
18289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // back to main framebuffer
18299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
18309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_SCISSOR_TEST);
18319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDeleteFramebuffersOES(1, &name);
183259119e658a12279e8fff508f8773843de2d90917Mathias Agopian
18339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *textureName = tname;
18349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *uOut = u;
18359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *vOut = v;
18369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
18379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
183859119e658a12279e8fff508f8773843de2d90917Mathias Agopian
18399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// ---------------------------------------------------------------------------
184059119e658a12279e8fff508f8773843de2d90917Mathias Agopian
18419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::electronBeamOffAnimationImplLocked()
18429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
18439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    status_t result = PERMISSION_DENIED;
184459119e658a12279e8fff508f8773843de2d90917Mathias Agopian
18459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
18469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return INVALID_OPERATION;
184759119e658a12279e8fff508f8773843de2d90917Mathias Agopian
18489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // get screen geometry
18499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
18509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_w = hw.getWidth();
18519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_h = hw.getHeight();
1852a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    const Region screenBounds(hw.getBounds());
185359119e658a12279e8fff508f8773843de2d90917Mathias Agopian
18549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat u, v;
18559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLuint tname;
18569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    result = renderScreenToTextureLocked(0, &tname, &u, &v);
18579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (result != NO_ERROR) {
18589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return result;
18599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
186059119e658a12279e8fff508f8773843de2d90917Mathias Agopian
18619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat vtx[8];
1862a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    const GLfloat texCoords[4][2] = { {0,0}, {0,v}, {u,v}, {u,0} };
18639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
18649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
18659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
18669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
18679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
18689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
18699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glVertexPointer(2, GL_FLOAT, 0, vtx);
18709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
1871ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    /*
1872ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     * Texture coordinate mapping
1873ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *
1874ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *                 u
1875ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *    1 +----------+---+
1876ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |     |    |   |  image is inverted
1877ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |     V    |   |  w.r.t. the texture
1878ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *  1-v +----------+   |  coordinates
1879ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |              |
1880ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |              |
1881ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |              |
1882ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *    0 +--------------+
1883ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      0              1
1884ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *
1885ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     */
1886ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian
18879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class s_curve_interpolator {
18889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float nbFrames, s, v;
18899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
18909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        s_curve_interpolator(int nbFrames, float s)
18919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : nbFrames(1.0f / (nbFrames-1)), s(s),
18929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian          v(1.0f + expf(-s + 0.5f*s)) {
18939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
18949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float operator()(int f) {
18959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const float x = f * nbFrames;
18969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f;
18979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
18989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
18999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class v_stretch {
19019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
19029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
19039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        v_stretch(uint32_t hw_w, uint32_t hw_h)
19049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
19059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
19069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
19079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w + (hw_w * v);
19089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = hw_h - (hw_h * v);
19099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
19109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
1911ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[0] = x;         vtx[1] = y;
1912ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
1913ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
1914ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
19159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
19169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
19179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class h_stretch {
19199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
19209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
19219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        h_stretch(uint32_t hw_w, uint32_t hw_h)
19229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
192359119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
19249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
19259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w - (hw_w * v);
19269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = 1.0f;
19279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
19289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
1929ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[0] = x;         vtx[1] = y;
1930ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
1931ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
1932ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
19339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
19349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
19359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // the full animation is 24 frames
1937ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    char value[PROPERTY_VALUE_MAX];
1938ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    property_get("debug.sf.electron_frames", value, "24");
1939ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    int nbFrames = (atoi(value) + 1) >> 1;
1940ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    if (nbFrames <= 0) // just in case
1941ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian        nbFrames = 24;
1942ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian
19439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itr(nbFrames, 7.5f);
19449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itg(nbFrames, 8.0f);
19459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itb(nbFrames, 8.5f);
19469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    v_stretch vverts(hw_w, hw_h);
1948a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian
1949a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glMatrixMode(GL_TEXTURE);
1950a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glLoadIdentity();
1951a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glMatrixMode(GL_MODELVIEW);
1952a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glLoadIdentity();
1953a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian
19549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnable(GL_BLEND);
19559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBlendFunc(GL_ONE, GL_ONE);
19569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=0 ; i<nbFrames ; i++) {
19579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float x, y, w, h;
19589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vr = itr(i);
19599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vg = itg(i);
19609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vb = itb(i);
19619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // clear screen
19639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(1,1,1,1);
19649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
19659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glEnable(GL_TEXTURE_2D);
196659119e658a12279e8fff508f8773843de2d90917Mathias Agopian
19679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the red plane
19689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vr);
19699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(1,0,0,1);
19709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
19719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the green plane
19739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vg);
19749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,1,0,1);
19759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
19769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the blue plane
19789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vb);
19799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,0,1,1);
19809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
19819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the white highlight (we use the last vertices)
198359119e658a12279e8fff508f8773843de2d90917Mathias Agopian        glDisable(GL_TEXTURE_2D);
198459119e658a12279e8fff508f8773843de2d90917Mathias Agopian        glColorMask(1,1,1,1);
19859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColor4f(vg, vg, vg, 1);
19869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
19879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
19889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
19899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    h_stretch hverts(hw_w, hw_h);
19919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_BLEND);
19929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_TEXTURE_2D);
19939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
19949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=0 ; i<nbFrames ; i++) {
19959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float v = itg(i);
19969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hverts(vtx, v);
19979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
19989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColor4f(1-v, 1-v, 1-v, 1);
19999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
20009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
20019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
20029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
20049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnable(GL_SCISSOR_TEST);
20059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
20069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDeleteTextures(1, &tname);
2007a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    glDisable(GL_TEXTURE_2D);
20089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
20099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
20109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::electronBeamOnAnimationImplLocked()
20129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
20139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    status_t result = PERMISSION_DENIED;
20149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
20169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return INVALID_OPERATION;
20179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // get screen geometry
20209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
20219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_w = hw.getWidth();
20229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_h = hw.getHeight();
20239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const Region screenBounds(hw.bounds());
20249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat u, v;
20269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLuint tname;
20279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    result = renderScreenToTextureLocked(0, &tname, &u, &v);
20289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (result != NO_ERROR) {
20299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return result;
20309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
20319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // back to main framebuffer
20339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
20349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_SCISSOR_TEST);
20359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat vtx[8];
20379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const GLfloat texCoords[4][2] = { {0,v}, {0,0}, {u,0}, {u,v} };
20389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
20399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
20409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
20419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
20429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
20439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
20449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glVertexPointer(2, GL_FLOAT, 0, vtx);
20459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class s_curve_interpolator {
20479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float nbFrames, s, v;
20489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
20499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        s_curve_interpolator(int nbFrames, float s)
20509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : nbFrames(1.0f / (nbFrames-1)), s(s),
20519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian          v(1.0f + expf(-s + 0.5f*s)) {
20529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
20539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float operator()(int f) {
20549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const float x = f * nbFrames;
20559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f;
20569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
20579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
20589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class v_stretch {
20609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
20619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
20629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        v_stretch(uint32_t hw_w, uint32_t hw_h)
20639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
206459119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
20659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
20669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w + (hw_w * v);
20679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = hw_h - (hw_h * v);
20689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
20699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
20709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[0] = x;         vtx[1] = y;
20719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
20729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
20739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
20749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
20759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
20769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class h_stretch {
20789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
20799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
20809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        h_stretch(uint32_t hw_w, uint32_t hw_h)
20819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
20829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
20839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
20849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w - (hw_w * v);
20859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = 1.0f;
20869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
20879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
20889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[0] = x;         vtx[1] = y;
20899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
20909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
20919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
20929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
20939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
20949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2095a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian    // the full animation is 12 frames
2096a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian    int nbFrames = 8;
20979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itr(nbFrames, 7.5f);
20989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itg(nbFrames, 8.0f);
20999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itb(nbFrames, 8.5f);
21009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    h_stretch hverts(hw_w, hw_h);
21029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_BLEND);
21039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_TEXTURE_2D);
21049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
21059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=nbFrames-1 ; i>=0 ; i--) {
21069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float v = itg(i);
21079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hverts(vtx, v);
21089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
21099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColor4f(1-v, 1-v, 1-v, 1);
21109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
21119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
21129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
21139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2114a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian    nbFrames = 4;
21159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    v_stretch vverts(hw_w, hw_h);
21169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnable(GL_BLEND);
21179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBlendFunc(GL_ONE, GL_ONE);
21189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=nbFrames-1 ; i>=0 ; i--) {
21199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float x, y, w, h;
21209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vr = itr(i);
21219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vg = itg(i);
21229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vb = itb(i);
212359119e658a12279e8fff508f8773843de2d90917Mathias Agopian
21249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // clear screen
212559119e658a12279e8fff508f8773843de2d90917Mathias Agopian        glColorMask(1,1,1,1);
21269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
21279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glEnable(GL_TEXTURE_2D);
21289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the red plane
21309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vr);
21319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(1,0,0,1);
21329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
21339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the green plane
21359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vg);
21369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,1,0,1);
21379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
21389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the blue plane
21409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vb);
21419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,0,1,1);
21429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
21439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
214559119e658a12279e8fff508f8773843de2d90917Mathias Agopian    }
214659119e658a12279e8fff508f8773843de2d90917Mathias Agopian
21479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
21489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnable(GL_SCISSOR_TEST);
21499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
215059119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glDeleteTextures(1, &tname);
2151a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    glDisable(GL_TEXTURE_2D);
215259119e658a12279e8fff508f8773843de2d90917Mathias Agopian
21539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
21549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
21559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// ---------------------------------------------------------------------------
21579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2158abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOffImplLocked(int32_t mode)
21599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
21609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    DisplayHardware& hw(graphicPlane(0).editDisplayHardware());
21619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (!hw.canDraw()) {
21629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // we're already off
21639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return NO_ERROR;
21649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
21657ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian
21667ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian    // turn off hwc while we're doing the animation
21677ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian    hw.getHwComposer().disable();
21687ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian    // and make sure to turn it back on (if needed) next time we compose
21697ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian    invalidateHwcGeometry();
21707ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian
2171abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    if (mode & ISurfaceComposer::eElectronBeamAnimationOff) {
2172abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        electronBeamOffAnimationImplLocked();
2173abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    }
2174abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian
2175abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    // always clear the whole screen at the end of the animation
2176abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    glClearColor(0,0,0,1);
2177abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    glDisable(GL_SCISSOR_TEST);
2178abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    glClear(GL_COLOR_BUFFER_BIT);
2179abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    glEnable(GL_SCISSOR_TEST);
2180abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    hw.flip( Region(hw.bounds()) );
2181abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian
2182015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian    return NO_ERROR;
218359119e658a12279e8fff508f8773843de2d90917Mathias Agopian}
218459119e658a12279e8fff508f8773843de2d90917Mathias Agopian
218559119e658a12279e8fff508f8773843de2d90917Mathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOff(int32_t mode)
218659119e658a12279e8fff508f8773843de2d90917Mathias Agopian{
218759119e658a12279e8fff508f8773843de2d90917Mathias Agopian    class MessageTurnElectronBeamOff : public MessageBase {
218859119e658a12279e8fff508f8773843de2d90917Mathias Agopian        SurfaceFlinger* flinger;
2189abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        int32_t mode;
219059119e658a12279e8fff508f8773843de2d90917Mathias Agopian        status_t result;
219159119e658a12279e8fff508f8773843de2d90917Mathias Agopian    public:
2192abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        MessageTurnElectronBeamOff(SurfaceFlinger* flinger, int32_t mode)
2193abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            : flinger(flinger), mode(mode), result(PERMISSION_DENIED) {
219459119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
219559119e658a12279e8fff508f8773843de2d90917Mathias Agopian        status_t getResult() const {
219659119e658a12279e8fff508f8773843de2d90917Mathias Agopian            return result;
219759119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
219859119e658a12279e8fff508f8773843de2d90917Mathias Agopian        virtual bool handler() {
219959119e658a12279e8fff508f8773843de2d90917Mathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
2200abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            result = flinger->turnElectronBeamOffImplLocked(mode);
220159119e658a12279e8fff508f8773843de2d90917Mathias Agopian            return true;
220259119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
220359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    };
220459119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2205abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    sp<MessageBase> msg = new MessageTurnElectronBeamOff(this, mode);
220659119e658a12279e8fff508f8773843de2d90917Mathias Agopian    status_t res = postMessageSync(msg);
220759119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (res == NO_ERROR) {
220859119e658a12279e8fff508f8773843de2d90917Mathias Agopian        res = static_cast<MessageTurnElectronBeamOff*>( msg.get() )->getResult();
22099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // work-around: when the power-manager calls us we activate the
22119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // animation. eventually, the "on" animation will be called
22129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // by the power-manager itself
2213abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        mElectronBeamAnimationMode = mode;
221459119e658a12279e8fff508f8773843de2d90917Mathias Agopian    }
221559119e658a12279e8fff508f8773843de2d90917Mathias Agopian    return res;
221659119e658a12279e8fff508f8773843de2d90917Mathias Agopian}
221759119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
2219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2220abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOnImplLocked(int32_t mode)
22219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
22229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    DisplayHardware& hw(graphicPlane(0).editDisplayHardware());
22239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (hw.canDraw()) {
22249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // we're already on
22259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return NO_ERROR;
22269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
2227abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    if (mode & ISurfaceComposer::eElectronBeamAnimationOn) {
2228abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        electronBeamOnAnimationImplLocked();
2229abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    }
2230a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian
2231a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian    // make sure to redraw the whole screen when the animation is done
2232a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian    mDirtyRegion.set(hw.bounds());
2233a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian    signalEvent();
2234a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian
2235015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian    return NO_ERROR;
22369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
22379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOn(int32_t mode)
22399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
22409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class MessageTurnElectronBeamOn : public MessageBase {
22419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        SurfaceFlinger* flinger;
2242abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        int32_t mode;
22439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        status_t result;
22449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
2245abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        MessageTurnElectronBeamOn(SurfaceFlinger* flinger, int32_t mode)
2246abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            : flinger(flinger), mode(mode), result(PERMISSION_DENIED) {
22479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
22489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        status_t getResult() const {
22499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return result;
22509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
22519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        virtual bool handler() {
22529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
2253abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            result = flinger->turnElectronBeamOnImplLocked(mode);
22549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return true;
22559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
22569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
22579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2258abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    postMessageAsync( new MessageTurnElectronBeamOn(this, mode) );
22599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
22609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
22619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// ---------------------------------------------------------------------------
22639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
226474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopianstatus_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy,
226574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        sp<IMemoryHeap>* heap,
226674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t* w, uint32_t* h, PixelFormat* f,
2267bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t sw, uint32_t sh,
2268bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ, uint32_t maxLayerZ)
226974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{
227074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    status_t result = PERMISSION_DENIED;
227174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
227274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // only one display supported for now
227374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
227474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return BAD_VALUE;
227574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
227674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
227774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return INVALID_OPERATION;
227874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
227974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // get screen geometry
228074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const DisplayHardware& hw(graphicPlane(dpy).displayHardware());
228174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const uint32_t hw_w = hw.getWidth();
228274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const uint32_t hw_h = hw.getHeight();
228374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
228474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    if ((sw > hw_w) || (sh > hw_h))
228574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return BAD_VALUE;
228674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
228774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    sw = (!sw) ? hw_w : sw;
228874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    sh = (!sh) ? hw_h : sh;
228974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const size_t size = sw * sh * 4;
229074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
22911c71a47a6db679a3212f0c99e14f330d6da500faMathias Agopian    //LOGD("screenshot: sw=%d, sh=%d, minZ=%d, maxZ=%d",
22921c71a47a6db679a3212f0c99e14f330d6da500faMathias Agopian    //        sw, sh, minLayerZ, maxLayerZ);
2293c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
229474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // make sure to clear all GL error flags
229574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    while ( glGetError() != GL_NO_ERROR ) ;
229674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
229774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // create a FBO
229874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    GLuint name, tname;
229974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glGenRenderbuffersOES(1, &tname);
230074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindRenderbufferOES(GL_RENDERBUFFER_OES, tname);
230174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA8_OES, sw, sh);
230274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glGenFramebuffersOES(1, &name);
230374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
230474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES,
230574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, tname);
230674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
230774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
2308c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
230974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    if (status == GL_FRAMEBUFFER_COMPLETE_OES) {
231074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
231174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // invert everything, b/c glReadPixel() below will invert the FB
231274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glViewport(0, 0, sw, sh);
2313f653b897a449e10d6cbfb6e0812f7b0bb02d6482Mathias Agopian        glScissor(0, 0, sw, sh);
2314ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian        glEnable(GL_SCISSOR_TEST);
231574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_PROJECTION);
231674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glPushMatrix();
231774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glLoadIdentity();
2318ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian        glOrthof(0, hw_w, hw_h, 0, 0, 1);
231974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_MODELVIEW);
232074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
232174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // redraw the screen entirely...
232274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glClearColor(0,0,0,1);
232374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
2324f653b897a449e10d6cbfb6e0812f7b0bb02d6482Mathias Agopian
23259575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        const LayerVector& layers(mDrawingState.layersSortedByZ);
23269575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        const size_t count = layers.size();
232774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        for (size_t i=0 ; i<count ; ++i) {
232874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            const sp<LayerBase>& layer(layers[i]);
2329b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian            const uint32_t flags = layer->drawingState().flags;
2330b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian            if (!(flags & ISurfaceComposer::eLayerHidden)) {
2331b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                const uint32_t z = layer->drawingState().z;
2332b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                if (z >= minLayerZ && z <= maxLayerZ) {
2333b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                    layer->drawForSreenShot();
2334b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                }
2335bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian            }
233674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        }
233774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
233874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // XXX: this is needed on tegra
2339ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian        glEnable(GL_SCISSOR_TEST);
234074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glScissor(0, 0, sw, sh);
234174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
234274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // check for errors and return screen capture
234374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        if (glGetError() != GL_NO_ERROR) {
234474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // error while rendering
234574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            result = INVALID_OPERATION;
234674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        } else {
234774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // allocate shared memory large enough to hold the
234874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // screen capture
234974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            sp<MemoryHeapBase> base(
235074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    new MemoryHeapBase(size, 0, "screen-capture") );
235174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            void* const ptr = base->getBase();
235274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            if (ptr) {
235374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                // capture the screen with glReadPixels()
235474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                glReadPixels(0, 0, sw, sh, GL_RGBA, GL_UNSIGNED_BYTE, ptr);
235574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                if (glGetError() == GL_NO_ERROR) {
235674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *heap = base;
235774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *w = sw;
235874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *h = sh;
235974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *f = PIXEL_FORMAT_RGBA_8888;
236074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    result = NO_ERROR;
236174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                }
236274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            } else {
236374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                result = NO_MEMORY;
236474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            }
236574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        }
236674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glEnable(GL_SCISSOR_TEST);
236774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glViewport(0, 0, hw_w, hw_h);
236874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_PROJECTION);
236974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glPopMatrix();
237074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_MODELVIEW);
237174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    } else {
237274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        result = BAD_VALUE;
237374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    }
237474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
237574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // release FBO resources
237674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
237774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glDeleteRenderbuffersOES(1, &tname);
237874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glDeleteFramebuffersOES(1, &name);
2379e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian
2380e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian    hw.compositionComplete();
2381e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian
23821c71a47a6db679a3212f0c99e14f330d6da500faMathias Agopian    // LOGD("screenshot: result = %s", result<0 ? strerror(result) : "OK");
2383c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
238474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    return result;
238574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian}
238674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
238774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
23881b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopianstatus_t SurfaceFlinger::captureScreen(DisplayID dpy,
23891b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        sp<IMemoryHeap>* heap,
239074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t* width, uint32_t* height, PixelFormat* format,
2391bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t sw, uint32_t sh,
2392bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ, uint32_t maxLayerZ)
23931b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian{
23941b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    // only one display supported for now
23951b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
23961b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        return BAD_VALUE;
23971b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
23981b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
23991b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        return INVALID_OPERATION;
24001b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
24011b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    class MessageCaptureScreen : public MessageBase {
24021b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        SurfaceFlinger* flinger;
24031b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        DisplayID dpy;
24041b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        sp<IMemoryHeap>* heap;
24051b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        uint32_t* w;
24061b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        uint32_t* h;
24071b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        PixelFormat* f;
240874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t sw;
240974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t sh;
2410bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ;
2411bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t maxLayerZ;
24121b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        status_t result;
24131b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    public:
24141b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        MessageCaptureScreen(SurfaceFlinger* flinger, DisplayID dpy,
241574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                sp<IMemoryHeap>* heap, uint32_t* w, uint32_t* h, PixelFormat* f,
2416bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                uint32_t sw, uint32_t sh,
2417bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                uint32_t minLayerZ, uint32_t maxLayerZ)
24181b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            : flinger(flinger), dpy(dpy),
2419bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              heap(heap), w(w), h(h), f(f), sw(sw), sh(sh),
2420bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              minLayerZ(minLayerZ), maxLayerZ(maxLayerZ),
2421bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              result(PERMISSION_DENIED)
24221b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
24231b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
24241b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        status_t getResult() const {
24251b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            return result;
24261b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
24271b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        virtual bool handler() {
24281b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
24291b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
24301b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            // if we have secure windows, never allow the screen capture
24311b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            if (flinger->mSecureFrameBuffer)
24321b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                return true;
24331b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
243474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            result = flinger->captureScreenImplLocked(dpy,
2435bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                    heap, w, h, f, sw, sh, minLayerZ, maxLayerZ);
24361b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
24371b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            return true;
24381b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
24391b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    };
24401b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
24411b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    sp<MessageBase> msg = new MessageCaptureScreen(this,
2442bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian            dpy, heap, width, height, format, sw, sh, minLayerZ, maxLayerZ);
24431b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    status_t res = postMessageSync(msg);
24441b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    if (res == NO_ERROR) {
24451b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        res = static_cast<MessageCaptureScreen*>( msg.get() )->getResult();
24461b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    }
24471b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    return res;
24481b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian}
24491b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
24501b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// ---------------------------------------------------------------------------
24511b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
2452b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<Layer> SurfaceFlinger::getLayer(const sp<ISurface>& sur) const
2453edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2454b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<Layer> result;
2455b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    Mutex::Autolock _l(mStateLock);
2456b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    result = mLayerMap.valueFor( sur->asBinder() ).promote();
2457b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return result;
2458b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
24597303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
2460b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// ---------------------------------------------------------------------------
246196f0819f81293076e652792794a961543e6750d7Mathias Agopian
2462b7e930db175c192464cebdeb49eb56cf6dd60114Mathias AgopianClient::Client(const sp<SurfaceFlinger>& flinger)
2463b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    : mFlinger(flinger), mNameGenerator(1)
2464b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{
2465edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2466edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
246796f0819f81293076e652792794a961543e6750d7Mathias AgopianClient::~Client()
246896f0819f81293076e652792794a961543e6750d7Mathias Agopian{
246996f0819f81293076e652792794a961543e6750d7Mathias Agopian    const size_t count = mLayers.size();
247096f0819f81293076e652792794a961543e6750d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
247196f0819f81293076e652792794a961543e6750d7Mathias Agopian        sp<LayerBaseClient> layer(mLayers.valueAt(i).promote());
247296f0819f81293076e652792794a961543e6750d7Mathias Agopian        if (layer != 0) {
247396f0819f81293076e652792794a961543e6750d7Mathias Agopian            mFlinger->removeLayer(layer);
247496f0819f81293076e652792794a961543e6750d7Mathias Agopian        }
2475edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2476edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2477076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
247896f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t Client::initCheck() const {
2479b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return NO_ERROR;
2480edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2481076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
24824f113740180b6512b43723c4728f262882dc9b45Mathias Agopiansize_t Client::attachLayer(const sp<LayerBaseClient>& layer)
2483edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
24844f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    Mutex::Autolock _l(mLock);
24854f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    size_t name = mNameGenerator++;
248696f0819f81293076e652792794a961543e6750d7Mathias Agopian    mLayers.add(name, layer);
248796f0819f81293076e652792794a961543e6750d7Mathias Agopian    return name;
2488edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2489edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2490b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianvoid Client::detachLayer(const LayerBaseClient* layer)
249196f0819f81293076e652792794a961543e6750d7Mathias Agopian{
24924f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    Mutex::Autolock _l(mLock);
249396f0819f81293076e652792794a961543e6750d7Mathias Agopian    // we do a linear search here, because this doesn't happen often
249496f0819f81293076e652792794a961543e6750d7Mathias Agopian    const size_t count = mLayers.size();
249596f0819f81293076e652792794a961543e6750d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
249696f0819f81293076e652792794a961543e6750d7Mathias Agopian        if (mLayers.valueAt(i) == layer) {
249796f0819f81293076e652792794a961543e6750d7Mathias Agopian            mLayers.removeItemsAt(i, 1);
249896f0819f81293076e652792794a961543e6750d7Mathias Agopian            break;
249996f0819f81293076e652792794a961543e6750d7Mathias Agopian        }
250096f0819f81293076e652792794a961543e6750d7Mathias Agopian    }
250196f0819f81293076e652792794a961543e6750d7Mathias Agopian}
25024f113740180b6512b43723c4728f262882dc9b45Mathias Agopiansp<LayerBaseClient> Client::getLayerUser(int32_t i) const
25034f113740180b6512b43723c4728f262882dc9b45Mathias Agopian{
25044f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    Mutex::Autolock _l(mLock);
2505076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBaseClient> lbc;
25064f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    wp<LayerBaseClient> layer(mLayers.valueFor(i));
250796f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (layer != 0) {
250896f0819f81293076e652792794a961543e6750d7Mathias Agopian        lbc = layer.promote();
250996f0819f81293076e652792794a961543e6750d7Mathias Agopian        LOGE_IF(lbc==0, "getLayerUser(name=%d) is dead", int(i));
2510076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
2511076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return lbc;
2512edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2513edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2514a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
2515a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianstatus_t Client::onTransact(
2516a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
2517a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian{
2518a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // these must be checked
2519a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     IPCThreadState* ipc = IPCThreadState::self();
2520a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     const int pid = ipc->getCallingPid();
2521a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     const int uid = ipc->getCallingUid();
2522a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     const int self_pid = getpid();
2523a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     if (UNLIKELY(pid != self_pid && uid != AID_GRAPHICS && uid != 0)) {
2524a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian         // we're called from a different process, do the real check
252599b49840d309727678b77403d6cc9f920111623fMathias Agopian         if (!PermissionCache::checkCallingPermission(sAccessSurfaceFlinger))
2526a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian         {
2527a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian             LOGE("Permission Denial: "
2528a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                     "can't openGlobalTransaction pid=%d, uid=%d", pid, uid);
2529a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian             return PERMISSION_DENIED;
2530a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian         }
2531a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     }
2532a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     return BnSurfaceComposerClient::onTransact(code, data, reply, flags);
2533edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2534a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
2535a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
253696f0819f81293076e652792794a961543e6750d7Mathias Agopiansp<ISurface> Client::createSurface(
25370ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        ISurfaceComposerClient::surface_data_t* params,
2538b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        const String8& name,
2539b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
2540edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t flags)
2541edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2542b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    /*
2543a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     * createSurface must be called from the GL thread so that it can
2544a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     * have access to the GL context.
2545b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     */
2546b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
2547a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    class MessageCreateSurface : public MessageBase {
2548a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        sp<ISurface> result;
2549a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        SurfaceFlinger* flinger;
2550a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        ISurfaceComposerClient::surface_data_t* params;
2551a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        Client* client;
2552a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        const String8& name;
2553a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        DisplayID display;
2554a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        uint32_t w, h;
2555a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        PixelFormat format;
2556a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        uint32_t flags;
2557a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    public:
2558a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        MessageCreateSurface(SurfaceFlinger* flinger,
2559a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                ISurfaceComposerClient::surface_data_t* params,
2560a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                const String8& name, Client* client,
2561a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
2562a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                uint32_t flags)
2563a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            : flinger(flinger), params(params), client(client), name(name),
2564a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian              display(display), w(w), h(h), format(format), flags(flags)
2565a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        {
2566579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        }
2567a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        sp<ISurface> getResult() const { return result; }
2568a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        virtual bool handler() {
2569a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            result = flinger->createSurface(params, name, client,
2570a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                    display, w, h, format, flags);
2571a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            return true;
2572b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        }
2573a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    };
2574b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
2575a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    sp<MessageBase> msg = new MessageCreateSurface(mFlinger.get(),
2576a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            params, name, this, display, w, h, format, flags);
2577a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    mFlinger->postMessageSync(msg);
2578a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    return static_cast<MessageCreateSurface*>( msg.get() )->getResult();
2579b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
2580a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianstatus_t Client::destroySurface(SurfaceID sid) {
2581a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    return mFlinger->removeSurface(this, sid);
2582b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
2583b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
2584b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// ---------------------------------------------------------------------------
2585edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
25869a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::GraphicBufferAlloc() {}
25879a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
25889a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::~GraphicBufferAlloc() {}
25899a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
25909a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h,
2591d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        PixelFormat format, uint32_t usage, status_t* error) {
25929a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(w, h, format, usage));
25939a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    status_t err = graphicBuffer->initCheck();
2594d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian    *error = err;
2595a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (err != 0 || graphicBuffer->handle == 0) {
2596d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        if (err == NO_MEMORY) {
2597d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian            GraphicBuffer::dumpAllocationsToSystemLog();
2598d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        }
2599a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        LOGE("GraphicBufferAlloc::createGraphicBuffer(w=%d, h=%d) "
2600a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian             "failed (%s), handle=%p",
2601a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                w, h, strerror(-err), graphicBuffer->handle);
26029a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis        return 0;
26039a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    }
26049a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    return graphicBuffer;
26059a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis}
26069a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
26079a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis// ---------------------------------------------------------------------------
26089a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
2609edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane::GraphicPlane()
2610edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    : mHw(0)
2611edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2612edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2613edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2614edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane::~GraphicPlane() {
2615edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    delete mHw;
2616edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2617edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2618edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool GraphicPlane::initialized() const {
2619edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return mHw ? true : false;
2620edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2621edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
26222b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianint GraphicPlane::getWidth() const {
26232b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    return mWidth;
2624edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2625edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
26262b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianint GraphicPlane::getHeight() const {
26272b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    return mHeight;
26282b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian}
26292b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
26302b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianvoid GraphicPlane::setDisplayHardware(DisplayHardware *hw)
26312b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian{
26322b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mHw = hw;
26332b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
26342b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    // initialize the display orientation transform.
26352b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    // it's a constant that should come from the display driver.
26362b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    int displayOrientation = ISurfaceComposer::eOrientationDefault;
26372b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    char property[PROPERTY_VALUE_MAX];
26382b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    if (property_get("ro.sf.hwrotation", property, NULL) > 0) {
26392b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        //displayOrientation
26402b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        switch (atoi(property)) {
26412b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        case 90:
26422b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            displayOrientation = ISurfaceComposer::eOrientation90;
26432b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            break;
26442b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        case 270:
26452b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            displayOrientation = ISurfaceComposer::eOrientation270;
26462b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            break;
26472b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        }
26482b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    }
26492b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
26502b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float w = hw->getWidth();
26512b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float h = hw->getHeight();
26522b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    GraphicPlane::orientationToTransfrom(displayOrientation, w, h,
26532b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            &mDisplayTransform);
26542b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    if (displayOrientation & ISurfaceComposer::eOrientationSwapMask) {
26552b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayWidth = h;
26562b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayHeight = w;
26572b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    } else {
26582b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayWidth = w;
26592b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayHeight = h;
26602b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    }
26612b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
26622b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    setOrientation(ISurfaceComposer::eOrientationDefault);
2663edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2664edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2665edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t GraphicPlane::orientationToTransfrom(
2666edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int orientation, int w, int h, Transform* tr)
2667eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian{
2668eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    uint32_t flags = 0;
2669edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (orientation) {
2670edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientationDefault:
2671eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_0;
2672eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        break;
2673edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientation90:
2674eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_90;
2675edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
2676edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientation180:
2677eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_180;
2678edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
2679edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientation270:
2680eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_270;
2681edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
2682edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    default:
2683edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return BAD_VALUE;
2684edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2685eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    tr->set(flags, w, h);
2686edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
2687edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2688edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2689edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t GraphicPlane::setOrientation(int orientation)
2690edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2691edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // If the rotation can be handled in hardware, this is where
2692edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // the magic should happen.
26932b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
26942b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const DisplayHardware& hw(displayHardware());
26952b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float w = mDisplayWidth;
26962b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float h = mDisplayHeight;
26972b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mWidth = int(w);
26982b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mHeight = int(h);
26992b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
27002b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    Transform orientationTransform;
2701eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    GraphicPlane::orientationToTransfrom(orientation, w, h,
2702eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian            &orientationTransform);
2703eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    if (orientation & ISurfaceComposer::eOrientationSwapMask) {
2704eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        mWidth = int(h);
2705eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        mHeight = int(w);
2706edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2707eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian
27080d1318b974feba2e6ff13e36a1781343c2fce045Mathias Agopian    mOrientation = orientation;
27092b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mGlobalTransform = mDisplayTransform * orientationTransform;
2710edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
2711edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2712edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2713edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst DisplayHardware& GraphicPlane::displayHardware() const {
2714edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return *mHw;
2715edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2716edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
271759119e658a12279e8fff508f8773843de2d90917Mathias AgopianDisplayHardware& GraphicPlane::editDisplayHardware() {
271859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    return *mHw;
271959119e658a12279e8fff508f8773843de2d90917Mathias Agopian}
272059119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2721edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst Transform& GraphicPlane::transform() const {
2722edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return mGlobalTransform;
2723edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2724edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2725076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias AgopianEGLDisplay GraphicPlane::getEGLDisplay() const {
2726076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return mHw->getEGLDisplay();
2727076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
2728076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
2729edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
2730edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2731edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
2732