SurfaceFlinger.cpp revision e6f43ddce78d6846af12550ff9193c5c6fe5844b
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
37d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian#include <gui/IDisplayEventConnection.h>
38d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
39edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String8.h>
40edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String16.h>
41edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/StopWatch.h>
42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
433330b203039dea366d4981db1408a460134b2d2cMathias Agopian#include <ui/GraphicBufferAllocator.h>
4435b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian#include <ui/GraphicLog.h>
45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/PixelFormat.h>
46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
47edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <pixelflinger/pixelflinger.h>
48edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <GLES/gl.h>
49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
50edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h"
51d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian#include "DisplayEventConnection.h"
52d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian#include "EventThread.h"
531f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian#include "GLExtensions.h"
548afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian#include "DdmConnection.h"
55edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h"
56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerDim.h"
57118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian#include "LayerScreenshot.h"
58edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h"
59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
60edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "DisplayHardware/DisplayHardware.h"
61a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian#include "DisplayHardware/HWComposer.h"
62edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
63a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian#include <private/surfaceflinger/SharedBufferStack.h>
64a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
65a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian/* ideally AID_GRAPHICS would be in a semi-public header
66a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian * or there would be a way to map a user/group name to its id
67a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian */
68a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian#ifndef AID_GRAPHICS
69a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian#define AID_GRAPHICS 1003
70a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian#endif
71a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian
72bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian#define EGL_VERSION_HW_ANDROID  0x3143
73bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
74edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DISPLAY_COUNT       1
75edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
76edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
77edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
78edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
7999b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sHardwareTest("android.permission.HARDWARE_TEST");
8099b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER");
8199b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER");
8299b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sDump("android.permission.DUMP");
8399b49840d309727678b77403d6cc9f920111623fMathias Agopian
8499b49840d309727678b77403d6cc9f920111623fMathias Agopian// ---------------------------------------------------------------------------
8599b49840d309727678b77403d6cc9f920111623fMathias Agopian
86edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::SurfaceFlinger()
87edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    :   BnSurfaceComposer(), Thread(false),
88edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mTransactionFlags(0),
8928378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        mTransationPending(false),
90076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved(false),
91edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mBootTime(systemTime()),
92edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mVisibleRegionsDirty(false),
93a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        mHwWorkListDirty(false),
94abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        mElectronBeamAnimationMode(0),
95edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDebugRegion(0),
96edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDebugBackground(0),
978afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian        mDebugDDMS(0),
9873d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian        mDebugDisableHWC(0),
99a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian        mDebugDisableTransformHint(0),
1009795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInSwapBuffers(0),
1019795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastSwapBufferTime(0),
1029795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInTransaction(0),
1039795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastTransactionTime(0),
1043330b203039dea366d4981db1408a460134b2d2cMathias Agopian        mBootFinished(false),
105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mConsoleSignals(0),
106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mSecureFrameBuffer(0)
107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    init();
109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::init()
112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
113a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI("SurfaceFlinger is starting");
114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // debugging stuff...
116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char value[PROPERTY_VALUE_MAX];
1178afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    property_get("debug.sf.showupdates", value, "0");
119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDebugRegion = atoi(value);
1208afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    property_get("debug.sf.showbackground", value, "0");
122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDebugBackground = atoi(value);
123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1248afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    property_get("debug.sf.ddms", value, "0");
1258afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    mDebugDDMS = atoi(value);
1268afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    if (mDebugDDMS) {
1278afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian        DdmConnection::start(getServiceName());
1288afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    }
1298afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
130a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI_IF(mDebugRegion,       "showupdates enabled");
131a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI_IF(mDebugBackground,   "showbackground enabled");
132a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI_IF(mDebugDDMS,         "DDMS debugging enabled");
133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::~SurfaceFlinger()
136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDeleteTextures(1, &mWormholeTexName);
138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1407303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopiansp<IMemoryHeap> SurfaceFlinger::getCblk() const
141edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1427303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    return mServerHeap;
143edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1457e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopiansp<ISurfaceComposerClient> SurfaceFlinger::createConnection()
146edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
14796f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<ISurfaceComposerClient> bclient;
14896f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<Client> client(new Client(this));
14996f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = client->initCheck();
15096f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR) {
15196f0819f81293076e652792794a961543e6750d7Mathias Agopian        bclient = client;
152edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return bclient;
154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1569a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc()
1579a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis{
1589a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc());
1599a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    return gba;
1609a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis}
161b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst GraphicPlane& SurfaceFlinger::graphicPlane(int dpy) const
163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
164e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block    ALOGE_IF(uint32_t(dpy) >= DISPLAY_COUNT, "Invalid DisplayID %d", dpy);
165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(mGraphicPlanes[dpy]);
166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return plane;
167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane& SurfaceFlinger::graphicPlane(int dpy)
170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return const_cast<GraphicPlane&>(
172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const_cast<SurfaceFlinger const *>(this)->graphicPlane(dpy));
173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::bootFinished()
176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t now = systemTime();
178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t duration = now - mBootTime;
179a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
1803330b203039dea366d4981db1408a460134b2d2cMathias Agopian    mBootFinished = true;
1811f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
1821f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // wait patiently for the window manager death
1831f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    const String16 name("window");
1841f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    sp<IBinder> window(defaultServiceManager()->getService(name));
1851f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    if (window != 0) {
1861f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian        window->linkToDeath(this);
1871f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    }
1881f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
1891f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // stop boot animation
190a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    property_set("ctl.stop", "bootanim");
191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1931f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopianvoid SurfaceFlinger::binderDied(const wp<IBinder>& who)
1941f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian{
1951f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // the window manager died on us. prepare its eulogy.
1961f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
1971f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // reset screen orientation
1981f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    setOrientation(0, eOrientationDefault, 0);
1991f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
2001f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // restart the boot-animation
2011f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    property_set("ctl.start", "bootanim");
2021f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian}
2031f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
204edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::onFirstRef()
205edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
206edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY);
207edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // Wait for the main thread to be done with its initialization
209edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mReadyToRunBarrier.wait();
210edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic inline uint16_t pack565(int r, int g, int b) {
213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return (r<<11)|(g<<5)|b;
214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::readyToRun()
217edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
218a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI(   "SurfaceFlinger's main thread ready to run. "
219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            "Initializing graphics H/W...");
220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // we only support one display currently
222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int dpy = 0;
223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    {
225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // initialize the main display
226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GraphicPlane& plane(graphicPlane(dpy));
227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        DisplayHardware* const hw = new DisplayHardware(this, dpy);
228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        plane.setDisplayHardware(hw);
229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2317303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    // create the shared control-block
2327303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    mServerHeap = new MemoryHeapBase(4096,
2337303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian            MemoryHeapBase::READ_ONLY, "SurfaceFlinger read-only heap");
234e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block    ALOGE_IF(mServerHeap==0, "can't create shared memory dealer");
2358b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
2367303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    mServerCblk = static_cast<surface_flinger_cblk_t*>(mServerHeap->getBase());
237e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block    ALOGE_IF(mServerCblk==0, "can't get to shared control block's address");
2388b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
2397303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    new(mServerCblk) surface_flinger_cblk_t;
2407303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize primary screen
242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // (other display should be initialized in the same manner, but
243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // asynchronously, as they could come and go. None of this is supported
244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // yet).
245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(graphicPlane(dpy));
246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw = plane.displayHardware();
247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint32_t w = hw.getWidth();
248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint32_t h = hw.getHeight();
249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint32_t f = hw.getFormat();
250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    hw.makeCurrent();
251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize the shared control block
253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mServerCblk->connected |= 1<<dpy;
254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    display_cblk_t* dcblk = mServerCblk->displays + dpy;
255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    memset(dcblk, 0, sizeof(display_cblk_t));
2562b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    dcblk->w            = plane.getWidth();
2572b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    dcblk->h            = plane.getHeight();
258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->format       = f;
259edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->orientation  = ISurfaceComposer::eOrientationDefault;
260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->xdpi         = hw.getDpiX();
261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->ydpi         = hw.getDpiY();
262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->fps          = hw.getRefreshRate();
263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->density      = hw.getDensity();
264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
265edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // Initialize OpenGL|ES
266edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
2678b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber    glPixelStorei(GL_PACK_ALIGNMENT, 4);
268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glEnableClientState(GL_VERTEX_ARRAY);
269edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glEnable(GL_SCISSOR_TEST);
270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glShadeModel(GL_FLAT);
271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_DITHER);
272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_CULL_FACE);
273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint16_t g0 = pack565(0x0F,0x1F,0x0F);
275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint16_t g1 = pack565(0x17,0x2f,0x17);
2769575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    const uint16_t wormholeTexData[4] = { g0, g1, g1, g0 };
277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glGenTextures(1, &mWormholeTexName);
278edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glBindTexture(GL_TEXTURE_2D, mWormholeTexName);
279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0,
2849575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis            GL_RGB, GL_UNSIGNED_SHORT_5_6_5, wormholeTexData);
2859575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis
2869575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    const uint16_t protTexData[] = { pack565(0x03, 0x03, 0x03) };
2879575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glGenTextures(1, &mProtectedTexName);
2889575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glBindTexture(GL_TEXTURE_2D, mProtectedTexName);
2899575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2909575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2919575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
2929575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
2939575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0,
2949575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis            GL_RGB, GL_UNSIGNED_SHORT_5_6_5, protTexData);
295edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glViewport(0, 0, w, h);
297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glMatrixMode(GL_PROJECTION);
298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glLoadIdentity();
299ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    // put the origin in the left-bottom corner
300ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    glOrthof(0, w, 0, h, 0, 1); // l=0, r=w ; b=0, t=h
301edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
302d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
303d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian    // start the EventThread
304d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian    mEventThread = new EventThread(this);
305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     *  We're now ready to accept clients...
308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
310d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian    mReadyToRunBarrier.open();
311d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
312a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    // start boot animation
313a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    property_set("ctl.start", "bootanim");
3148b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
315edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if 0
320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark -
321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark Events Handler
322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif
323edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
324f61c57fe2e955e1c195bb0ca2dd7bcdaa922d5a9Mathias Agopianvoid SurfaceFlinger::waitForEvent() {
325f61c57fe2e955e1c195bb0ca2dd7bcdaa922d5a9Mathias Agopian    mEventQueue.waitMessage();
326edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
327edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
328edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::signalEvent() {
329f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    mEventQueue.invalidate();
330edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
331edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
332d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg,
333d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian        nsecs_t reltime, uint32_t flags) {
334d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian    return mEventQueue.postMessage(msg, reltime);
335d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian}
336d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
337d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,
338d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian        nsecs_t reltime, uint32_t flags) {
339d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian    status_t res = mEventQueue.postMessage(msg, reltime);
340d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian    if (res == NO_ERROR) {
341d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian        msg->wait();
342d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian    }
343d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian    return res;
344d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian}
345d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
346d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian// ----------------------------------------------------------------------------
347d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
348582270d69db94286a248bd829f1ae6f910d45124Jamie Gennisbool SurfaceFlinger::authenticateSurfaceTexture(
349582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis        const sp<ISurfaceTexture>& surfaceTexture) const {
350134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    Mutex::Autolock _l(mStateLock);
351582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis    sp<IBinder> surfaceTextureBinder(surfaceTexture->asBinder());
352134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
353134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // Check the visible layer list for the ISurface
354134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
355134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    size_t count = currentLayers.size();
356134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    for (size_t i=0 ; i<count ; i++) {
357134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        const sp<LayerBase>& layer(currentLayers[i]);
358134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        sp<LayerBaseClient> lbc(layer->getLayerBaseClient());
359582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis        if (lbc != NULL) {
360582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder();
361582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            if (lbcBinder == surfaceTextureBinder) {
362582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis                return true;
363582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            }
364134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        }
365134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    }
366134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
367134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // Check the layers in the purgatory.  This check is here so that if a
368582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis    // SurfaceTexture gets destroyed before all the clients are done using it,
369582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis    // the error will not be reported as "surface XYZ is not authenticated", but
370134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // will instead fail later on when the client tries to use the surface,
371134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // which should be reported as "surface XYZ returned an -ENODEV".  The
372134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // purgatorized layers are no less authentic than the visible ones, so this
373134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // should not cause any harm.
374134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    size_t purgatorySize =  mLayerPurgatory.size();
375134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    for (size_t i=0 ; i<purgatorySize ; i++) {
376134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
377134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        sp<LayerBaseClient> lbc(layer->getLayerBaseClient());
378582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis        if (lbc != NULL) {
379582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder();
380582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            if (lbcBinder == surfaceTextureBinder) {
381582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis                return true;
382582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            }
383134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        }
384134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    }
385134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
386134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    return false;
387134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis}
388134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
389d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian// ----------------------------------------------------------------------------
390d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
391d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopiansp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection() {
392478ae5eb5a0047e1b2988c896cff6363b455ee50Mathias Agopian    sp<DisplayEventConnection> result(new DisplayEventConnection(mEventThread));
393d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian    return result;
394bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian}
395bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
396edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
397edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if 0
398edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark -
399edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark Main loop
400edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif
401edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
402edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool SurfaceFlinger::threadLoop()
403edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
404edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    waitForEvent();
405edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
406edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // check for transactions
40799ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten    if (CC_UNLIKELY(mConsoleSignals)) {
408edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        handleConsoleEvents();
409edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
410edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
411698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    // if we're in a global transaction, don't do anything.
412698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
413698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    uint32_t transactionFlags = peekTransactionFlags(mask);
41499ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten    if (CC_UNLIKELY(transactionFlags)) {
415698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        handleTransaction(transactionFlags);
416edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
417edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
418edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // post surfaces (if needed)
419edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    handlePageFlip();
420edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
4213a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian    if (mDirtyRegion.isEmpty()) {
4223a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian        // nothing new to do.
4233a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian        return true;
4243a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian    }
4253a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian
42699ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten    if (CC_UNLIKELY(mHwWorkListDirty)) {
427a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        // build the h/w work list
428a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        handleWorkList();
429a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
430a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
431edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw(graphicPlane(0).displayHardware());
43299ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten    if (CC_LIKELY(hw.canDraw())) {
433edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // repaint the framebuffer (if needed)
43435b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian
43535b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        const int index = hw.getCurrentBufferIndex();
43635b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        GraphicLog& logger(GraphicLog::getInstance());
43735b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian
43835b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        logger.log(GraphicLog::SF_REPAINT, index);
439edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        handleRepaint();
440edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
44174faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian        // inform the h/w that we're done compositing
44235b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        logger.log(GraphicLog::SF_COMPOSITION_COMPLETE, index);
44374faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian        hw.compositionComplete();
44474faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian
44535b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        logger.log(GraphicLog::SF_SWAP_BUFFERS, index);
4468392b504bdf63ac7820c79c7217a89f2b2411bd0Antti Hatala        postFramebuffer();
4478392b504bdf63ac7820c79c7217a89f2b2411bd0Antti Hatala
44835b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        logger.log(GraphicLog::SF_REPAINT_DONE, index);
449edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
450edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // pretend we did the post
451e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian        hw.compositionComplete();
452d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian        hw.waitForVSync();
453edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
454edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return true;
455edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
456edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
457edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer()
458edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
4593a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian    // this should never happen. we do the flip anyways so we don't
4603a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian    // risk to cause a deadlock with hwc
46132397c1cd3327905173b36baa6fd1c579bc328ffSteve Block    ALOGW_IF(mSwapRegion.isEmpty(), "mSwapRegion is empty");
462a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
463a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    const nsecs_t now = systemTime();
464a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = now;
465a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    hw.flip(mSwapRegion);
466a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mLastSwapBufferTime = systemTime() - now;
467a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = 0;
468a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mSwapRegion.clear();
469edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
470edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
471edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleConsoleEvents()
472edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
473edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // something to do with the console
474edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw = graphicPlane(0).displayHardware();
475edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
476edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int what = android_atomic_and(0, &mConsoleSignals);
477edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (what & eConsoleAcquired) {
478edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        hw.acquireScreen();
4799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // this is a temporary work-around, eventually this should be called
4809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // by the power-manager
481abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        SurfaceFlinger::turnElectronBeamOn(mElectronBeamAnimationMode);
482edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
483edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
484edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (what & eConsoleReleased) {
48559119e658a12279e8fff508f8773843de2d90917Mathias Agopian        if (hw.isScreenAcquired()) {
486edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            hw.releaseScreen();
487edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
488edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
489edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
490edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDirtyRegion.set(hw.bounds());
491edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
492edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
493edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
494edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
495ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    Mutex::Autolock _l(mStateLock);
496ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    const nsecs_t now = systemTime();
497ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = now;
498ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
499ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // Here we're guaranteed that some transaction flags are set
500ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // so we can call handleTransactionLocked() unconditionally.
501ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // We call getTransactionFlags(), which will also clear the flags,
502ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // with mStateLock held to guarantee that mCurrentState won't change
503ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // until the transaction is committed.
504ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
505ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
506ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    transactionFlags = getTransactionFlags(mask);
507ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    handleTransactionLocked(transactionFlags);
508ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
509ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mLastTransactionTime = systemTime() - now;
510ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = 0;
511ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    invalidateHwcGeometry();
512ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // here the transaction has been committed
5133d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian}
514edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
515ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopianvoid SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
5163d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{
5173d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    const LayerVector& currentLayers(mCurrentState.layersSortedByZ);
518edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t count = currentLayers.size();
519edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
520edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
521edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Traversal of the children
522edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * (perform the transaction for each of them if needed)
523edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
524edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
525edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const bool layersNeedTransaction = transactionFlags & eTraversalNeeded;
526edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (layersNeedTransaction) {
527edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (size_t i=0 ; i<count ; i++) {
528076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            const sp<LayerBase>& layer = currentLayers[i];
529edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
530edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (!trFlags) continue;
531edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
532edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const uint32_t flags = layer->doTransaction(0);
533edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (flags & Layer::eVisibleRegion)
534edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mVisibleRegionsDirty = true;
535edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
536edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
537edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
538edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
539edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Perform our own transaction if needed
540edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
541edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
542edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (transactionFlags & eTransactionNeeded) {
543edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (mCurrentState.orientation != mDrawingState.orientation) {
544edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // the orientation has changed, recompute all visible regions
545edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // and invalidate everything.
546edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
547edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int dpy = 0;
548edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int orientation = mCurrentState.orientation;
54921230c6410bdab13cd2bd274da54b1e4061b6035Jeff Brown            // Currently unused: const uint32_t flags = mCurrentState.orientationFlags;
550edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            GraphicPlane& plane(graphicPlane(dpy));
551edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            plane.setOrientation(orientation);
552edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
553edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // update the shared control block
554edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const DisplayHardware& hw(plane.displayHardware());
555edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            volatile display_cblk_t* dcblk = mServerCblk->displays + dpy;
556edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dcblk->orientation = orientation;
5572b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            dcblk->w = plane.getWidth();
5582b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            dcblk->h = plane.getHeight();
559edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
560edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
561edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mDirtyRegion.set(hw.bounds());
562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
563edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5640aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        if (currentLayers.size() > mDrawingState.layersSortedByZ.size()) {
5650aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            // layers have been added
566edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
567edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
568edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5690aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        // some layers might have been removed, so
5700aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        // we need to update the regions they're exposing.
5710aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        if (mLayersRemoved) {
57248d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian            mLayersRemoved = false;
573edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
5740aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            const LayerVector& previousLayers(mDrawingState.layersSortedByZ);
5753d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian            const size_t count = previousLayers.size();
5763d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian            for (size_t i=0 ; i<count ; i++) {
5770aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                const sp<LayerBase>& layer(previousLayers[i]);
5780aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                if (currentLayers.indexOf( layer ) < 0) {
5790aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                    // this layer is not visible anymore
5805d7126b625c8c4a7b945e8c247b63abff7bc13b6Mathias Agopian                    mDirtyRegionRemovedLayer.orSelf(layer->visibleRegionScreen);
5810aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                }
5820aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            }
583edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
584edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
585edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
586edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    commitTransaction();
587edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
588edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
589edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::computeVisibleRegions(
5901bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian    const LayerVector& currentLayers, Region& dirtyRegion, Region& opaqueRegion)
591edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
592edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(graphicPlane(0));
593edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Transform& planeTransform(plane.transform());
594ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian    const DisplayHardware& hw(plane.displayHardware());
595ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian    const Region screenRegion(hw.bounds());
596edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
597edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveOpaqueLayers;
598edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveCoveredLayers;
599edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region dirty;
600edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
601edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    bool secureFrameBuffer = false;
602edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
603edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t i = currentLayers.size();
604edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    while (i--) {
605076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        const sp<LayerBase>& layer = currentLayers[i];
606edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->validateVisibility(planeTransform);
607edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
608edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // start with the whole surface at its current location
609970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian        const Layer::State& s(layer->drawingState());
610edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
611ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
612ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * opaqueRegion: area of a surface that is fully opaque.
613ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
614edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region opaqueRegion;
615ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
616ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
617ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visibleRegion: area of a surface that is visible on screen
618ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * and not fully transparent. This is essentially the layer's
619ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * footprint minus the opaque regions above it.
620ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * Areas covered by a translucent surface are considered visible.
621ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
622edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region visibleRegion;
623ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
624ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
625ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * coveredRegion: area of a surface that is covered by all
626ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visible regions above it (which includes the translucent areas).
627ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
628edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region coveredRegion;
629ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
630ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
631ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // handle hidden surfaces by setting the visible region to empty
63299ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten        if (CC_LIKELY(!(s.flags & ISurfaceComposer::eLayerHidden) && s.alpha)) {
633a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            const bool translucent = !layer->isOpaque();
634970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian            const Rect bounds(layer->visibleBounds());
635edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            visibleRegion.set(bounds);
636ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            visibleRegion.andSelf(screenRegion);
637ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            if (!visibleRegion.isEmpty()) {
638ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // Remove the transparent area from the visible region
639ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (translucent) {
640ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    visibleRegion.subtractSelf(layer->transparentRegionScreen);
641ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
642edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
643ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // compute the opaque region
644ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                const int32_t layerOrientation = layer->getOrientation();
645ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (s.alpha==255 && !translucent &&
646ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                        ((layerOrientation & Transform::ROT_INVALID) == false)) {
647ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    // the opaque region is the layer's footprint
648ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    opaqueRegion = visibleRegion;
649ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
650edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
651edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
652edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
653ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Clip the covered region to the visible region
654ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        coveredRegion = aboveCoveredLayers.intersect(visibleRegion);
655ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
656ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveCoveredLayers for next (lower) layer
657ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        aboveCoveredLayers.orSelf(visibleRegion);
658ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
659edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // subtract the opaque region covered by the layers above us
660edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        visibleRegion.subtractSelf(aboveOpaqueLayers);
661edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
662edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // compute this layer's dirty region
663edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (layer->contentDirty) {
664edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // we need to invalidate the whole region
665edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dirty = visibleRegion;
666edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // as well, as the old visible region
667edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dirty.orSelf(layer->visibleRegionScreen);
668edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->contentDirty = false;
669edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
670a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian            /* compute the exposed region:
671ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   the exposed region consists of two components:
672ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   1) what's VISIBLE now and was COVERED before
673ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   2) what's EXPOSED now less what was EXPOSED before
674ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
675ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * note that (1) is conservative, we start with the whole
676ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * visible region but only keep what used to be covered by
677ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * something -- which mean it may have been exposed.
678ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
679ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * (2) handles areas that were not covered by anything but got
680ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * exposed because of a resize.
681a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian             */
682ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region newExposed = visibleRegion - coveredRegion;
683ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldVisibleRegion = layer->visibleRegionScreen;
684ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldCoveredRegion = layer->coveredRegionScreen;
685ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldExposed = oldVisibleRegion - oldCoveredRegion;
686ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed);
687edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
688edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirty.subtractSelf(aboveOpaqueLayers);
689edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
690edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // accumulate to the screen dirty region
691edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirtyRegion.orSelf(dirty);
692edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
693ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveOpaqueLayers for next (lower) layer
694edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        aboveOpaqueLayers.orSelf(opaqueRegion);
6958b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
696edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // Store the visible region is screen space
697edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setVisibleRegion(visibleRegion);
698edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setCoveredRegion(coveredRegion);
699edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
700970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian        // If a secure layer is partially visible, lock-down the screen!
701edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (layer->isSecure() && !visibleRegion.isEmpty()) {
702edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            secureFrameBuffer = true;
703edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
704edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
705edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
706970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian    // invalidate the areas where a layer was removed
707970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian    dirtyRegion.orSelf(mDirtyRegionRemovedLayer);
708970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian    mDirtyRegionRemovedLayer.clear();
709970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian
710edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mSecureFrameBuffer = secureFrameBuffer;
711edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    opaqueRegion = aboveOpaqueLayers;
712edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
713edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
714edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
715edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::commitTransaction()
716edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
7172f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall    if (!mLayersPendingRemoval.isEmpty()) {
7182f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall        // Notify removed layers now that they can't be drawn from
7192f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall        for (size_t i = 0; i < mLayersPendingRemoval.size(); i++) {
7202f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall            mLayersPendingRemoval[i]->onRemoved();
7212f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall        }
7222f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall        mLayersPendingRemoval.clear();
7232f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall    }
7242f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall
725edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDrawingState = mCurrentState;
72628378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    mTransationPending = false;
727cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mTransactionCV.broadcast();
728edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
729edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
730edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handlePageFlip()
731edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
732edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    bool visibleRegions = mVisibleRegionsDirty;
7331bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian    const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
734edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    visibleRegions |= lockPageFlip(currentLayers);
735edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
736edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const DisplayHardware& hw = graphicPlane(0).displayHardware();
737edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const Region screenRegion(hw.bounds());
738edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (visibleRegions) {
739edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            Region opaqueRegion;
740edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            computeVisibleRegions(currentLayers, mDirtyRegion, opaqueRegion);
7414da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
7424da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            /*
7434da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian             *  rebuild the visible layer list
7444da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian             */
7451bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian            const size_t count = currentLayers.size();
7464da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            mVisibleLayersSortedByZ.clear();
7474da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            mVisibleLayersSortedByZ.setCapacity(count);
7484da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            for (size_t i=0 ; i<count ; i++) {
7494da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian                if (!currentLayers[i]->visibleRegionScreen.isEmpty())
7504da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian                    mVisibleLayersSortedByZ.add(currentLayers[i]);
7514da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            }
7524da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
753edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mWormholeRegion = screenRegion.subtract(opaqueRegion);
754edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = false;
755ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian            invalidateHwcGeometry();
756edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
757edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
758edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    unlockPageFlip(currentLayers);
7590dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian
7600dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    mDirtyRegion.orSelf(getAndClearInvalidateRegion());
761edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDirtyRegion.andSelf(screenRegion);
762edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
763edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
764ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopianvoid SurfaceFlinger::invalidateHwcGeometry()
765ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian{
766ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian    mHwWorkListDirty = true;
767ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian}
768ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian
769edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool SurfaceFlinger::lockPageFlip(const LayerVector& currentLayers)
770edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
771edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    bool recomputeVisibleRegions = false;
772edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t count = currentLayers.size();
773076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBase> const* layers = currentLayers.array();
774edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (size_t i=0 ; i<count ; i++) {
775b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
776edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->lockPageFlip(recomputeVisibleRegions);
777edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
778edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return recomputeVisibleRegions;
779edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
780edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
781edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::unlockPageFlip(const LayerVector& currentLayers)
782edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
783edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(graphicPlane(0));
784edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Transform& planeTransform(plane.transform());
785edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t count = currentLayers.size();
786076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBase> const* layers = currentLayers.array();
787edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (size_t i=0 ; i<count ; i++) {
788b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
789edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->unlockPageFlip(planeTransform, mDirtyRegion);
790edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
791edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
792edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
793a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopianvoid SurfaceFlinger::handleWorkList()
794a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian{
795a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    mHwWorkListDirty = false;
796a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    HWComposer& hwc(graphicPlane(0).displayHardware().getHwComposer());
797a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    if (hwc.initCheck() == NO_ERROR) {
798a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        const Vector< sp<LayerBase> >& currentLayers(mVisibleLayersSortedByZ);
799a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        const size_t count = currentLayers.size();
800a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        hwc.createWorkList(count);
80145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        hwc_layer_t* const cur(hwc.getLayers());
80245721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        for (size_t i=0 ; cur && i<count ; i++) {
80345721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            currentLayers[i]->setGeometry(&cur[i]);
80453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian            if (mDebugDisableHWC || mDebugRegion) {
80573d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian                cur[i].compositionType = HWC_FRAMEBUFFER;
80673d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian                cur[i].flags |= HWC_SKIP_LAYER;
80773d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian            }
808a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        }
809a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
810a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian}
811b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian
812edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleRepaint()
813edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
814b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // compute the invalid region
8150656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian    mSwapRegion.orSelf(mDirtyRegion);
816edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
81799ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten    if (CC_UNLIKELY(mDebugRegion)) {
818edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        debugFlashRegions();
819edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
820edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
821b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // set the frame buffer
822b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
823b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    glMatrixMode(GL_MODELVIEW);
824b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    glLoadIdentity();
825edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
826edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t flags = hw.getFlags();
8278b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber    if ((flags & DisplayHardware::SWAP_RECTANGLE) ||
8288b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber        (flags & DisplayHardware::BUFFER_PRESERVED))
829df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian    {
83029d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // we can redraw only what's dirty, but since SWAP_RECTANGLE only
83129d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // takes a rectangle, we must make sure to update that whole
83229d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // rectangle in that case
83329d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        if (flags & DisplayHardware::SWAP_RECTANGLE) {
834b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            // TODO: we really should be able to pass a region to
83529d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // SWAP_RECTANGLE so that we don't have to redraw all this.
8360656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian            mDirtyRegion.set(mSwapRegion.bounds());
83729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        } else {
83829d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // in the BUFFER_PRESERVED case, obviously, we can update only
83929d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // what's needed and nothing more.
84029d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // NOTE: this is NOT a common case, as preserving the backbuffer
84129d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // is costly and usually involves copying the whole update back.
84229d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        }
843edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
84495a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian        if (flags & DisplayHardware::PARTIAL_UPDATES) {
84529d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // We need to redraw the rectangle that will be updated
846df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian            // (pushed to the framebuffer).
84795a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian            // This is needed because PARTIAL_UPDATES only takes one
84829d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // rectangle instead of a region (see DisplayHardware::flip())
8490656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian            mDirtyRegion.set(mSwapRegion.bounds());
850edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
85129d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // we need to redraw everything (the whole screen)
852edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mDirtyRegion.set(hw.bounds());
8530656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian            mSwapRegion = mDirtyRegion;
854edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
855edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
856edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
8579c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    setupHardwareComposer(mDirtyRegion);
858edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    composeSurfaces(mDirtyRegion);
859edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
8609c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    // update the swap region and clear the dirty region
8619c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    mSwapRegion.orSelf(mDirtyRegion);
862edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDirtyRegion.clear();
863edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
864edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
8659c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopianvoid SurfaceFlinger::setupHardwareComposer(Region& dirtyInOut)
866edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
867f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
868f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    HWComposer& hwc(hw.getHwComposer());
869f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    hwc_layer_t* const cur(hwc.getLayers());
870f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    if (!cur) {
8719c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        return;
872edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
873a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
8744da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian    const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
87545721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    size_t count = layers.size();
876a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
877e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block    ALOGE_IF(hwc.getNumLayers() != count,
87845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            "HAL number of layers (%d) doesn't match surfaceflinger (%d)",
87945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            hwc.getNumLayers(), count);
880a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
88145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    // just to be extra-safe, use the smallest count
88224925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling    if (hwc.initCheck() == NO_ERROR) {
88324925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling        count = count < hwc.getNumLayers() ? count : hwc.getNumLayers();
88424925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling    }
885a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
88645721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    /*
88745721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     *  update the per-frame h/w composer data for each layer
88845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     *  and build the transparent region of the FB
88945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     */
890f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
891f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
892f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        layer->setPerFrameData(&cur[i]);
893f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    }
8949c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    const size_t fbLayerCount = hwc.getLayerCount(HWC_FRAMEBUFFER);
895f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    status_t err = hwc.prepare();
896e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block    ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
897f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian
898f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    if (err == NO_ERROR) {
8999c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // what's happening here is tricky.
9009c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // we want to clear all the layers with the CLEAR_FB flags
9019c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // that are opaque.
9029c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // however, since some GPU are efficient at preserving
9039c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // the backbuffer, we want to take advantage of that so we do the
9049c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // clear only in the dirty region (other areas will be preserved
9059c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // on those GPUs).
9069c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        //   NOTE: on non backbuffer preserving GPU, the dirty region
9079c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        //   has already been expanded as needed, so the code is correct
9089c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        //   there too.
9099c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        //
9109c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // However, the content of the framebuffer cannot be trusted when
9119c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // we switch to/from FB/OVERLAY, in which case we need to
9129c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // expand the dirty region to those areas too.
9139c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        //
9149c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // Note also that there is a special case when switching from
9159c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // "no layers in FB" to "some layers in FB", where we need to redraw
9169c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // the entire FB, since some areas might contain uninitialized
9179c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // data.
9189c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        //
9199c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // Also we want to make sure to not clear areas that belong to
9203a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian        // layers above that won't redraw (we would just be erasing them),
9219c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // that is, we can't erase anything outside the dirty region.
922a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
9239c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        Region transparent;
924f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian
9259c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        if (!fbLayerCount && hwc.getLayerCount(HWC_FRAMEBUFFER)) {
9269c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian            transparent.set(hw.getBounds());
9279c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian            dirtyInOut = transparent;
9289c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        } else {
9299c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian            for (size_t i=0 ; i<count ; i++) {
9309c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                const sp<LayerBase>& layer(layers[i]);
9319c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                if ((cur[i].hints & HWC_HINT_CLEAR_FB) && layer->isOpaque()) {
9329c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                    transparent.orSelf(layer->visibleRegionScreen);
9339c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                }
9349c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                bool isOverlay = (cur[i].compositionType != HWC_FRAMEBUFFER);
9359c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                if (isOverlay != layer->isOverlay()) {
9369c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                    // we transitioned to/from overlay, so add this layer
9379c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                    // to the dirty region so the framebuffer can be either
9389c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                    // cleared or redrawn.
9399c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                    dirtyInOut.orSelf(layer->visibleRegionScreen);
9409c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                }
9419c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                layer->setOverlay(isOverlay);
942f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian            }
9439c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian            // don't erase stuff outside the dirty region
9449c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian            transparent.andSelf(dirtyInOut);
945f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        }
946f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian
947f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        /*
948f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian         *  clear the area of the FB that need to be transparent
949f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian         */
950f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        if (!transparent.isEmpty()) {
951f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian            glClearColor(0,0,0,0);
952f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian            Region::const_iterator it = transparent.begin();
953f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian            Region::const_iterator const end = transparent.end();
954f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian            const int32_t height = hw.getHeight();
955f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian            while (it != end) {
956f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian                const Rect& r(*it++);
957f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian                const GLint sy = height - (r.top + r.height());
958f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian                glScissor(r.left, sy, r.width(), r.height());
959f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian                glClear(GL_COLOR_BUFFER_BIT);
960f20a32415d055336bc6016fa2de36d126db32746Mathias Agopian            }
961a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        }
962a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
963f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian}
964f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian
965f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopianvoid SurfaceFlinger::composeSurfaces(const Region& dirty)
966f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian{
967cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
968cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian    HWComposer& hwc(hw.getHwComposer());
969cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian
970cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian    const size_t fbLayerCount = hwc.getLayerCount(HWC_FRAMEBUFFER);
97199ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten    if (CC_UNLIKELY(fbLayerCount && !mWormholeRegion.isEmpty())) {
972f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        // should never happen unless the window manager has a bug
973f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        // draw something...
974f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        drawWormhole();
975f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    }
97645721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian
97745721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    /*
97845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     * and then, render the layers targeted at the framebuffer
97945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     */
980cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian    hwc_layer_t* const cur(hwc.getLayers());
981f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
982f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    size_t count = layers.size();
98345721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
9849c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        if (cur && (cur[i].compositionType != HWC_FRAMEBUFFER)) {
985f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian            continue;
98645721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        }
98745721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
98845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        const Region clip(dirty.intersect(layer->visibleRegionScreen));
98945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        if (!clip.isEmpty()) {
99045721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            layer->draw(clip);
99145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        }
99245721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    }
993edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
994edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
995edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::debugFlashRegions()
996edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
9970a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
9980a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    const uint32_t flags = hw.getFlags();
99953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian    const int32_t height = hw.getHeight();
10000656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian    if (mSwapRegion.isEmpty()) {
100153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian        return;
100253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian    }
10030a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
10040a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    if (!((flags & DisplayHardware::SWAP_RECTANGLE) ||
10050a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian            (flags & DisplayHardware::BUFFER_PRESERVED))) {
10060a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        const Region repaint((flags & DisplayHardware::PARTIAL_UPDATES) ?
10070a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian                mDirtyRegion.bounds() : hw.bounds());
10080a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        composeSurfaces(repaint);
10090a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    }
10100a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
1011c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_EXTERNAL_OES);
1012c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_2D);
1013edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_BLEND);
1014edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_SCISSOR_TEST);
1015edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
10160926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    static int toggle = 0;
10170926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    toggle = 1 - toggle;
10180926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    if (toggle) {
10190a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        glColor4f(1, 0, 1, 1);
10200926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    } else {
10210a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        glColor4f(1, 1, 0, 1);
10220926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    }
1023edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
102420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    Region::const_iterator it = mDirtyRegion.begin();
102520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    Region::const_iterator const end = mDirtyRegion.end();
102620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    while (it != end) {
102720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        const Rect& r = *it++;
1028edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLfloat vertices[][2] = {
102953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.left,  height - r.top },
103053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.left,  height - r.bottom },
103153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.right, height - r.bottom },
103253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.right, height - r.top }
1033edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        };
1034edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glVertexPointer(2, GL_FLOAT, 0, vertices);
1035edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1036edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
10370a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
10380656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian    hw.flip(mSwapRegion);
1039edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1040edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mDebugRegion > 1)
10410a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        usleep(mDebugRegion * 1000);
1042edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1043edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glEnable(GL_SCISSOR_TEST);
1044edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1045edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1046edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::drawWormhole() const
1047edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1048edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Region region(mWormholeRegion.intersect(mDirtyRegion));
1049edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (region.isEmpty())
1050edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1051edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1052edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw(graphicPlane(0).displayHardware());
1053edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int32_t width = hw.getWidth();
1054edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int32_t height = hw.getHeight();
1055edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
105699ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten    if (CC_LIKELY(!mDebugBackground)) {
10570a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        glClearColor(0,0,0,0);
105820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        Region::const_iterator it = region.begin();
105920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        Region::const_iterator const end = region.end();
106020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        while (it != end) {
106120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            const Rect& r = *it++;
1062edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const GLint sy = height - (r.top + r.height());
1063edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glScissor(r.left, sy, r.width(), r.height());
1064edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glClear(GL_COLOR_BUFFER_BIT);
1065edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1066edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
1067edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GLshort vertices[][2] = { { 0, 0 }, { width, 0 },
1068edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                { width, height }, { 0, height }  };
1069edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GLshort tcoords[][2] = { { 0, 0 }, { 1, 0 },  { 1, 1 }, { 0, 1 } };
1070c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian
1071edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glVertexPointer(2, GL_SHORT, 0, vertices);
1072edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glTexCoordPointer(2, GL_SHORT, 0, tcoords);
1073edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
1074c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian
1075c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian        glDisable(GL_TEXTURE_EXTERNAL_OES);
1076edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glEnable(GL_TEXTURE_2D);
1077edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glBindTexture(GL_TEXTURE_2D, mWormholeTexName);
1078edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1079edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glMatrixMode(GL_TEXTURE);
1080edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glLoadIdentity();
1081c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian
1082c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian        glDisable(GL_BLEND);
1083c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian
1084edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glScalef(width*(1.0f/32.0f), height*(1.0f/32.0f), 1);
108520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        Region::const_iterator it = region.begin();
108620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        Region::const_iterator const end = region.end();
108720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        while (it != end) {
108820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            const Rect& r = *it++;
1089edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const GLint sy = height - (r.top + r.height());
1090edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glScissor(r.left, sy, r.width(), r.height());
1091edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1092edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1093edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1094a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        glDisable(GL_TEXTURE_2D);
1095ebeb7095961e09f5cff0c7cf2c04fa4770b2e033Mathias Agopian        glLoadIdentity();
1096ebeb7095961e09f5cff0c7cf2c04fa4770b2e033Mathias Agopian        glMatrixMode(GL_MODELVIEW);
1097edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1098edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1099edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::debugShowFPS() const
1101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    static int mFrameCount;
1103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    static int mLastFrameCount = 0;
1104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    static nsecs_t mLastFpsTime = 0;
1105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    static float mFps = 0;
1106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mFrameCount++;
1107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    nsecs_t now = systemTime();
1108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    nsecs_t diff = now - mLastFpsTime;
1109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (diff > ms2ns(250)) {
1110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mFps =  ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff;
1111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mLastFpsTime = now;
1112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mLastFrameCount = mFrameCount;
1113edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // XXX: mFPS has the value we want
1115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project }
1116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1117076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::addLayer(const sp<LayerBase>& layer)
1118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
1120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    addLayer_l(layer);
1121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
1122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1125076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::addLayer_l(const sp<LayerBase>& layer)
1126edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1127f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian    ssize_t i = mCurrentState.layersSortedByZ.add(layer);
11281b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    return (i < 0) ? status_t(i) : status_t(NO_ERROR);
11291b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian}
11301b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
113196f0819f81293076e652792794a961543e6750d7Mathias Agopianssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
113296f0819f81293076e652792794a961543e6750d7Mathias Agopian        const sp<LayerBaseClient>& lbc)
11331b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
113496f0819f81293076e652792794a961543e6750d7Mathias Agopian    // attach this layer to the client
11354f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    size_t name = client->attachLayer(lbc);
11364f113740180b6512b43723c4728f262882dc9b45Mathias Agopian
11374f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    Mutex::Autolock _l(mStateLock);
113896f0819f81293076e652792794a961543e6750d7Mathias Agopian
113996f0819f81293076e652792794a961543e6750d7Mathias Agopian    // add this layer to the current state list
114096f0819f81293076e652792794a961543e6750d7Mathias Agopian    addLayer_l(lbc);
114196f0819f81293076e652792794a961543e6750d7Mathias Agopian
11424f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    return ssize_t(name);
114396f0819f81293076e652792794a961543e6750d7Mathias Agopian}
114496f0819f81293076e652792794a961543e6750d7Mathias Agopian
114596f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer)
114696f0819f81293076e652792794a961543e6750d7Mathias Agopian{
114796f0819f81293076e652792794a961543e6750d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
114896f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = purgatorizeLayer_l(layer);
114996f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR)
115096f0819f81293076e652792794a961543e6750d7Mathias Agopian        setTransactionFlags(eTransactionNeeded);
115196f0819f81293076e652792794a961543e6750d7Mathias Agopian    return err;
1152edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1154076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase)
1155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1156b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<LayerBaseClient> lbc(layerBase->getLayerBaseClient());
1157b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (lbc != 0) {
11580d1561275e80073807ac04728951782d943f8882Mathias Agopian        mLayerMap.removeItem( lbc->getSurfaceBinder() );
1159b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    }
1160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase);
1161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (index >= 0) {
1162076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved = true;
1163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
1164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
11653d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    return status_t(index);
1166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
11689a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase)
11699a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
117076cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    // First add the layer to the purgatory list, which makes sure it won't
117176cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    // go away, then remove it from the main list (through a transaction).
11729a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    ssize_t err = removeLayer_l(layerBase);
117376cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    if (err >= 0) {
117476cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian        mLayerPurgatory.add(layerBase);
117576cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    }
11768c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian
11772f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall    mLayersPendingRemoval.push(layerBase);
11780b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian
11793d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // it's possible that we don't find a layer, because it might
11803d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // have been destroyed already -- this is not technically an error
118196f0819f81293076e652792794a961543e6750d7Mathias Agopian    // from the user because there is a race between Client::destroySurface(),
118296f0819f81293076e652792794a961543e6750d7Mathias Agopian    // ~Client() and ~ISurface().
11839a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err;
11849a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
11859a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
118696f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::invalidateLayerVisibility(const sp<LayerBase>& layer)
1187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
118896f0819f81293076e652792794a961543e6750d7Mathias Agopian    layer->forceVisibilityTransaction();
118996f0819f81293076e652792794a961543e6750d7Mathias Agopian    setTransactionFlags(eTraversalNeeded);
119096f0819f81293076e652792794a961543e6750d7Mathias Agopian    return NO_ERROR;
1191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1193dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopianuint32_t SurfaceFlinger::peekTransactionFlags(uint32_t flags)
1194dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian{
1195dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian    return android_atomic_release_load(&mTransactionFlags);
1196dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian}
1197dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian
1198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags)
1199edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1200edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return android_atomic_and(~flags, &mTransactionFlags) & flags;
1201edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1202edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1203bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags)
1204edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1205edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t old = android_atomic_or(flags, &mTransactionFlags);
1206edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((old & flags)==0) { // wake the server up
1207bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        signalEvent();
1208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1209edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return old;
1210edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1213b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennisvoid SurfaceFlinger::setTransactionState(const Vector<ComposerState>& state,
121428378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        int orientation, uint32_t flags) {
1215698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
1216cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
121728378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    uint32_t transactionFlags = 0;
1218b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis    if (mCurrentState.orientation != orientation) {
1219b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis        if (uint32_t(orientation)<=eOrientation270 || orientation==42) {
1220b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis            mCurrentState.orientation = orientation;
122128378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis            transactionFlags |= eTransactionNeeded;
1222b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis        } else if (orientation != eOrientationUnchanged) {
122332397c1cd3327905173b36baa6fd1c579bc328ffSteve Block            ALOGW("setTransactionState: ignoring unrecognized orientation: %d",
1224b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis                    orientation);
1225b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis        }
1226b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis    }
1227b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis
1228698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    const size_t count = state.size();
1229698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
1230698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const ComposerState& s(state[i]);
1231698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        sp<Client> client( static_cast<Client *>(s.client.get()) );
123228378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        transactionFlags |= setClientStateLocked(client, s.state);
1233698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    }
1234386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian
123528378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    if (transactionFlags) {
1236386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // this triggers the transaction
123728378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        setTransactionFlags(transactionFlags);
1238698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian
1239386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // if this is a synchronous transaction, wait for it to take effect
1240386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // before returning.
1241386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        if (flags & eSynchronous) {
1242386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            mTransationPending = true;
1243386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        }
1244386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        while (mTransationPending) {
1245386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
1246386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            if (CC_UNLIKELY(err != NO_ERROR)) {
1247386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                // just in case something goes wrong in SF, return to the
1248386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                // called after a few seconds.
124932397c1cd3327905173b36baa6fd1c579bc328ffSteve Block                ALOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!");
1250386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                mTransationPending = false;
1251386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                break;
1252386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            }
1253cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        }
1254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
12578b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huberint SurfaceFlinger::setOrientation(DisplayID dpy,
1258c08731e756868653d09d3e49b723706df3687070Mathias Agopian        int orientation, uint32_t flags)
1259edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
126099ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten    if (CC_UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
1261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return BAD_VALUE;
1262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
1264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mCurrentState.orientation != orientation) {
1265edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (uint32_t(orientation)<=eOrientation270 || orientation==42) {
126621230c6410bdab13cd2bd274da54b1e4061b6035Jeff Brown            mCurrentState.orientationFlags = flags;
1267edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mCurrentState.orientation = orientation;
1268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            setTransactionFlags(eTransactionNeeded);
1269edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mTransactionCV.wait(mStateLock);
1270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
1271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            orientation = BAD_VALUE;
1272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return orientation;
1275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
12770ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopiansp<ISurface> SurfaceFlinger::createSurface(
12780ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        ISurfaceComposerClient::surface_data_t* params,
12790ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const String8& name,
12800ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const sp<Client>& client,
1281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        DisplayID d, uint32_t w, uint32_t h, PixelFormat format,
1282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t flags)
1283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1284076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBaseClient> layer;
1285a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    sp<ISurface> surfaceHandle;
12866e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian
12876e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    if (int32_t(w|h) < 0) {
1288e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE("createSurface() failed, w or h is negative (w=%d, h=%d)",
12896e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian                int(w), int(h));
12906e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian        return surfaceHandle;
12916e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    }
12928b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
12939d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block    //ALOGD("createSurface for pid %d (%d x %d)", pid, w, h);
1294b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<Layer> normalLayer;
1295edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (flags & eFXSurfaceMask) {
1296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceNormal:
1297a5529c8778c2f407f482fc12165aeb76c0f505c2Mathias Agopian            normalLayer = createNormalSurface(client, d, w, h, flags, format);
1298a5529c8778c2f407f482fc12165aeb76c0f505c2Mathias Agopian            layer = normalLayer;
1299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
1300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceBlur:
13011293a8eb567fd63c072a6970fa9dcf37d076059fMathias Agopian            // for now we treat Blur as Dim, until we can implement it
13021293a8eb567fd63c072a6970fa9dcf37d076059fMathias Agopian            // efficiently.
1303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceDim:
130496f0819f81293076e652792794a961543e6750d7Mathias Agopian            layer = createDimSurface(client, d, w, h, flags);
1305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
1306118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        case eFXSurfaceScreenshot:
1307118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian            layer = createScreenshotSurface(client, d, w, h, flags);
1308118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian            break;
1309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1310edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1311076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (layer != 0) {
131296f0819f81293076e652792794a961543e6750d7Mathias Agopian        layer->initStates(w, h, flags);
1313285dbde2e0cd0057be070ded3be8f5f453147edcMathias Agopian        layer->setName(name);
131496f0819f81293076e652792794a961543e6750d7Mathias Agopian        ssize_t token = addClientLayer(client, layer);
1315b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        surfaceHandle = layer->getSurface();
13178b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber        if (surfaceHandle != 0) {
131896f0819f81293076e652792794a961543e6750d7Mathias Agopian            params->token = token;
1319a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            params->identity = layer->getIdentity();
1320b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            if (normalLayer != 0) {
1321b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian                Mutex::Autolock _l(mStateLock);
1322a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                mLayerMap.add(layer->getSurfaceBinder(), normalLayer);
1323b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            }
13241c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        }
1325b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
132696f0819f81293076e652792794a961543e6750d7Mathias Agopian        setTransactionFlags(eTransactionNeeded);
1327edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1328edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1329edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return surfaceHandle;
1330edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1331edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1332b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<Layer> SurfaceFlinger::createNormalSurface(
1333f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        const sp<Client>& client, DisplayID display,
133496f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags,
13351c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        PixelFormat& format)
1336edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1337edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize the surfaces
1338edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (format) { // TODO: take h/w into account
1339edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSPARENT:
1340edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSLUCENT:
1341edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        format = PIXEL_FORMAT_RGBA_8888;
1342edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1343edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_OPAQUE:
1344a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888
1345a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian        format = PIXEL_FORMAT_RGB_565;
1346a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#else
13478f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian        format = PIXEL_FORMAT_RGBX_8888;
1348a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif
1349edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1350edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1351edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1352a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888
1353a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian    if (format == PIXEL_FORMAT_RGBX_8888)
1354a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian        format = PIXEL_FORMAT_RGBA_8888;
1355a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif
1356a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian
135796f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<Layer> layer = new Layer(this, display, client);
1358f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian    status_t err = layer->setBuffers(w, h, format, flags);
135999ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten    if (CC_LIKELY(err != NO_ERROR)) {
1360e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE("createNormalSurfaceLocked() failed (%s)", strerror(-err));
1361076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        layer.clear();
1362edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1363edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1364edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1365edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1366b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<LayerDim> SurfaceFlinger::createDimSurface(
1367f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        const sp<Client>& client, DisplayID display,
136896f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags)
1369edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
137096f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<LayerDim> layer = new LayerDim(this, display, client);
1371118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    return layer;
1372118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
1373118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
1374118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopiansp<LayerScreenshot> SurfaceFlinger::createScreenshotSurface(
1375118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        const sp<Client>& client, DisplayID display,
1376118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags)
1377118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{
1378118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    sp<LayerScreenshot> layer = new LayerScreenshot(this, display, client);
1379edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1380edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1381edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
138296f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeSurface(const sp<Client>& client, SurfaceID sid)
13839a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
13849a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    /*
13859a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     * called by the window manager, when a surface should be marked for
13869a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     * destruction.
13878b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber     *
13880aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * The surface is removed from the current and drawing lists, but placed
13890aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * in the purgatory queue, so it's not destroyed right-away (we need
13900aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * to wait for all client's references to go away first).
13919a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     */
13929a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
139348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    status_t err = NAME_NOT_FOUND;
13940aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian    Mutex::Autolock _l(mStateLock);
139596f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<LayerBaseClient> layer = client->getLayerUser(sid);
139648d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    if (layer != 0) {
139748d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        err = purgatorizeLayer_l(layer);
139848d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        if (err == NO_ERROR) {
139948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian            setTransactionFlags(eTransactionNeeded);
140048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        }
14019a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    }
14029a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return err;
14039a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
14049a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
1405ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopianstatus_t SurfaceFlinger::destroySurface(const wp<LayerBaseClient>& layer)
1406edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1407759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian    // called by ~ISurface() when all references are gone
1408ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    status_t err = NO_ERROR;
1409ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    sp<LayerBaseClient> l(layer.promote());
1410ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    if (l != NULL) {
1411ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        Mutex::Autolock _l(mStateLock);
1412ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        err = removeLayer_l(l);
1413ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        if (err == NAME_NOT_FOUND) {
1414ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // The surface wasn't in the current list, which means it was
1415ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // removed already, which means it is in the purgatory,
1416ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // and need to be removed from there.
1417ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            ssize_t idx = mLayerPurgatory.remove(l);
1418e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block            ALOGE_IF(idx < 0,
1419ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian                    "layer=%p is not in the purgatory list", l.get());
1420f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        }
1421e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE_IF(err<0 && err != NAME_NOT_FOUND,
1422ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian                "error removing layer=%p (%s)", l.get(), strerror(-err));
1423ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    }
1424ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    return err;
1425edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1426edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1427698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopianuint32_t SurfaceFlinger::setClientStateLocked(
142896f0819f81293076e652792794a961543e6750d7Mathias Agopian        const sp<Client>& client,
1429698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const layer_state_t& s)
1430edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1431edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t flags = 0;
1432698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    sp<LayerBaseClient> layer(client->getLayerUser(s.surface));
1433698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    if (layer != 0) {
1434698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const uint32_t what = s.what;
1435698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & ePositionChanged) {
1436698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setPosition(s.x, s.y))
1437698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1438698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1439698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eLayerChanged) {
1440698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
1441698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setLayer(s.z)) {
1442698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                mCurrentState.layersSortedByZ.removeAt(idx);
1443698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                mCurrentState.layersSortedByZ.add(layer);
1444698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                // we need traversal (state changed)
1445698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                // AND transaction (list changed)
1446698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTransactionNeeded|eTraversalNeeded;
1447edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1448698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1449698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eSizeChanged) {
1450698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setSize(s.w, s.h)) {
1451698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1452edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1453edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1454698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eAlphaChanged) {
1455698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f)))
1456698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1457698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1458698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eMatrixChanged) {
1459698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setMatrix(s.matrix))
1460698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1461698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1462698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eTransparentRegionChanged) {
1463698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setTransparentRegionHint(s.transparentRegion))
1464698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1465698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1466698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eVisibilityChanged) {
1467698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setFlags(s.flags, s.mask))
1468698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1469698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1470edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1471698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    return flags;
1472edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1473edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1474edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::screenReleased(int dpy)
1475edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1476edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // this may be called by a signal handler, we can't do too much in here
1477edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    android_atomic_or(eConsoleReleased, &mConsoleSignals);
1478edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    signalEvent();
1479edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1480edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1481edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::screenAcquired(int dpy)
1482edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1483edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // this may be called by a signal handler, we can't do too much in here
1484edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    android_atomic_or(eConsoleAcquired, &mConsoleSignals);
1485edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    signalEvent();
1486edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1487edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1488edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
1489edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
14901d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling    const size_t SIZE = 4096;
1491edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char buffer[SIZE];
1492edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    String8 result;
149399b49840d309727678b77403d6cc9f920111623fMathias Agopian
149499b49840d309727678b77403d6cc9f920111623fMathias Agopian    if (!PermissionCache::checkCallingPermission(sDump)) {
1495edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        snprintf(buffer, SIZE, "Permission Denial: "
1496edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                "can't dump SurfaceFlinger from pid=%d, uid=%d\n",
1497edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                IPCThreadState::self()->getCallingPid(),
1498edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                IPCThreadState::self()->getCallingUid());
1499edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        result.append(buffer);
1500edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
15019795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
15029795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // figure out if we're stuck somewhere
15039795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const nsecs_t now = systemTime();
15049795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const nsecs_t inSwapBuffers(mDebugInSwapBuffers);
15059795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const nsecs_t inTransaction(mDebugInTransaction);
15069795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0;
15079795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0;
15089795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
15099795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // Try to get the main lock, but don't insist if we can't
15109795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // (this would indicate SF is stuck, but we want to be able to
15119795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // print something in dumpsys).
15129795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        int retry = 3;
15139795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        while (mStateLock.tryLock()<0 && --retry>=0) {
15149795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            usleep(1000000);
15159795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
15169795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const bool locked(retry >= 0);
15179795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (!locked) {
15188b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber            snprintf(buffer, SIZE,
15199795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "SurfaceFlinger appears to be unresponsive, "
15209795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "dumping anyways (no locks held)\n");
15219795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            result.append(buffer);
15229795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
15239795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
152448b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        /*
152548b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian         * Dump the visible layer list
152648b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian         */
1527edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
1528edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const size_t count = currentLayers.size();
152948b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        snprintf(buffer, SIZE, "Visible layers (count = %d)\n", count);
153048b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        result.append(buffer);
1531edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (size_t i=0 ; i<count ; i++) {
15321b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            const sp<LayerBase>& layer(currentLayers[i]);
15331b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            layer->dump(result, buffer, SIZE);
15341b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            const Layer::State& s(layer->drawingState());
1535edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            s.transparentRegion.dump(result, "transparentRegion");
1536edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->transparentRegionScreen.dump(result, "transparentRegionScreen");
1537edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->visibleRegionScreen.dump(result, "visibleRegionScreen");
1538edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
15391b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
154048b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        /*
154148b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian         * Dump the layers in the purgatory
154248b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian         */
154348b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
1544bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian        const size_t purgatorySize = mLayerPurgatory.size();
154548b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        snprintf(buffer, SIZE, "Purgatory state (%d entries)\n", purgatorySize);
154648b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        result.append(buffer);
154748b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        for (size_t i=0 ; i<purgatorySize ; i++) {
154848b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian            const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
154948b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian            layer->shortDump(result, buffer, SIZE);
155048b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        }
155148b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
155248b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        /*
155348b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian         * Dump SurfaceFlinger global state
155448b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian         */
155548b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
1556ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian        snprintf(buffer, SIZE, "SurfaceFlinger global state:\n");
155748b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        result.append(buffer);
1558ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian
1559ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian        const GLExtensions& extensions(GLExtensions::getInstance());
1560ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian        snprintf(buffer, SIZE, "GLES: %s, %s, %s\n",
1561ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian                extensions.getVendor(),
1562ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian                extensions.getRenderer(),
1563ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian                extensions.getVersion());
1564ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian        result.append(buffer);
1565bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
1566bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian        snprintf(buffer, SIZE, "EGL : %s\n",
1567bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian                eglQueryString(graphicPlane(0).getEGLDisplay(),
1568bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian                        EGL_VERSION_HW_ANDROID));
1569bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian        result.append(buffer);
1570bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
1571ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian        snprintf(buffer, SIZE, "EXTS: %s\n", extensions.getExtension());
1572ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian        result.append(buffer);
1573ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian
1574edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mWormholeRegion.dump(result, "WormholeRegion");
1575edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const DisplayHardware& hw(graphicPlane(0).displayHardware());
1576edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        snprintf(buffer, SIZE,
1577a402c4c9913cfbc6c3da21719c57a93a11f091f0Jamie Gennis                "  orientation=%d, canDraw=%d\n",
1578edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mCurrentState.orientation, hw.canDraw());
1579edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        result.append(buffer);
15809795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        snprintf(buffer, SIZE,
15819795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                "  last eglSwapBuffers() time: %f us\n"
1582d5e4ef9e439317e2525a51106dbc509d3982de24Mathias Agopian                "  last transaction time     : %f us\n"
1583d5e4ef9e439317e2525a51106dbc509d3982de24Mathias Agopian                "  refresh-rate              : %f fps\n"
1584d5e4ef9e439317e2525a51106dbc509d3982de24Mathias Agopian                "  x-dpi                     : %f\n"
1585d5e4ef9e439317e2525a51106dbc509d3982de24Mathias Agopian                "  y-dpi                     : %f\n",
1586d5e4ef9e439317e2525a51106dbc509d3982de24Mathias Agopian                mLastSwapBufferTime/1000.0,
1587d5e4ef9e439317e2525a51106dbc509d3982de24Mathias Agopian                mLastTransactionTime/1000.0,
1588d5e4ef9e439317e2525a51106dbc509d3982de24Mathias Agopian                hw.getRefreshRate(),
1589d5e4ef9e439317e2525a51106dbc509d3982de24Mathias Agopian                hw.getDpiX(),
1590d5e4ef9e439317e2525a51106dbc509d3982de24Mathias Agopian                hw.getDpiY());
15919795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        result.append(buffer);
15921b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
15939795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (inSwapBuffersDuration || !locked) {
15949795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            snprintf(buffer, SIZE, "  eglSwapBuffers time: %f us\n",
15959795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    inSwapBuffersDuration/1000.0);
15969795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            result.append(buffer);
15979795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
15981b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
15999795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (inTransactionDuration || !locked) {
16009795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            snprintf(buffer, SIZE, "  transaction time: %f us\n",
16019795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    inTransactionDuration/1000.0);
16029795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            result.append(buffer);
16039795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
16041b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
160548b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        /*
1606d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian         * VSYNC state
1607d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian         */
1608d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian        mEventThread->dump(result, buffer, SIZE);
1609d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
1610d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian        /*
161148b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian         * Dump HWComposer state
161248b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian         */
161373d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian        HWComposer& hwc(hw.getHwComposer());
1614d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian        snprintf(buffer, SIZE, "h/w composer state:\n");
1615d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian        result.append(buffer);
161673d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian        snprintf(buffer, SIZE, "  h/w composer %s and %s\n",
161773d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian                hwc.initCheck()==NO_ERROR ? "present" : "not present",
161853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                (mDebugDisableHWC || mDebugRegion) ? "disabled" : "enabled");
161973d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian        result.append(buffer);
162022da60c3e64cd57535cbba063c07127814a2b52fMathias Agopian        hwc.dump(result, buffer, SIZE, mVisibleLayersSortedByZ);
162173d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian
162248b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        /*
162348b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian         * Dump gralloc state
162448b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian         */
16253330b203039dea366d4981db1408a460134b2d2cMathias Agopian        const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
1626076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        alloc.dump(result);
16271d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling        hw.dump(result);
16289795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
16299795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (locked) {
16309795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            mStateLock.unlock();
16319795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
1632edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1633edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    write(fd, result.string(), result.size());
1634edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1635edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1636edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1637edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::onTransact(
1638edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
1639edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1640edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (code) {
1641edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case CREATE_CONNECTION:
1642698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        case SET_TRANSACTION_STATE:
1643edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case SET_ORIENTATION:
1644edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case BOOT_FINISHED:
164559119e658a12279e8fff508f8773843de2d90917Mathias Agopian        case TURN_ELECTRON_BEAM_OFF:
16469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        case TURN_ELECTRON_BEAM_ON:
1647edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        {
1648edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // codes that require permission check
1649edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            IPCThreadState* ipc = IPCThreadState::self();
1650edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int pid = ipc->getCallingPid();
1651a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian            const int uid = ipc->getCallingUid();
165299b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
165399b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) {
1654e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block                ALOGE("Permission Denial: "
1655375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                        "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
1656375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                return PERMISSION_DENIED;
1657edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
16581b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
16591b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
16601b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        case CAPTURE_SCREEN:
16611b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
16621b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            // codes that require permission check
16631b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
16641b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int pid = ipc->getCallingPid();
16651b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int uid = ipc->getCallingUid();
166699b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
166799b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) {
1668e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block                ALOGE("Permission Denial: "
16691b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                        "can't read framebuffer pid=%d, uid=%d", pid, uid);
16701b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                return PERMISSION_DENIED;
16711b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            }
16721b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
1673edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1674edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
16751b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
1676edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
1677edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
1678b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        CHECK_INTERFACE(ISurfaceComposer, data, reply);
167999ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten        if (CC_UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) {
1680375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
1681375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int pid = ipc->getCallingPid();
1682375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int uid = ipc->getCallingUid();
1683e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block            ALOGE("Permission Denial: "
1684375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                    "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
1685edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return PERMISSION_DENIED;
1686edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1687edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int n;
1688edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        switch (code) {
168901b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian            case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE
169035b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian            case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE
1691edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1692edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1002:  // SHOW_UPDATES
1693edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                n = data.readInt32();
1694edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDebugRegion = n ? n : (mDebugRegion ? 0 : 1);
169553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
169653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
1697edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1698edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1003:  // SHOW_BACKGROUND
1699edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                n = data.readInt32();
1700edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDebugBackground = n ? 1 : 0;
1701edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1702edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1004:{ // repaint everything
170353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
1704cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
1705cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            }
1706cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            case 1005:{ // force transaction
1707cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
1708cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
1709edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
171035b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian            case 1006:{ // enable/disable GraphicLog
171135b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian                int enabled = data.readInt32();
171235b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian                GraphicLog::getInstance().setEnabled(enabled);
171335b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian                return NO_ERROR;
171435b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian            }
171553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian            case 1008:  // toggle use of hw composer
171653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                n = data.readInt32();
171753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                mDebugDisableHWC = n ? 1 : 0;
171853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
171953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
172053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                return NO_ERROR;
1721a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian            case 1009:  // toggle use of transform hint
1722a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                n = data.readInt32();
1723a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                mDebugDisableTransformHint = n ? 1 : 0;
1724a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                invalidateHwcGeometry();
1725a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                repaintEverything();
1726a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                return NO_ERROR;
1727edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1010:  // interrogate.
172801b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian                reply->writeInt32(0);
1729edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(0);
1730edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(mDebugRegion);
1731edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(mDebugBackground);
1732edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1733edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1013: {
1734edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                Mutex::Autolock _l(mStateLock);
1735edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                const DisplayHardware& hw(graphicPlane(0).displayHardware());
1736edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(hw.getPageFlipCount());
1737edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1738edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return NO_ERROR;
1739edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1740edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1741edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return err;
1742edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1743edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
174453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopianvoid SurfaceFlinger::repaintEverything() {
174553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
17460dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    const Rect bounds(hw.getBounds());
17470dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    setInvalidateRegion(Region(bounds));
174853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian    signalEvent();
174953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian}
175053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian
17510dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopianvoid SurfaceFlinger::setInvalidateRegion(const Region& reg) {
17520dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    Mutex::Autolock _l(mInvalidateLock);
17530dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    mInvalidateRegion = reg;
17540dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian}
17550dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian
17560dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias AgopianRegion SurfaceFlinger::getAndClearInvalidateRegion() {
17570dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    Mutex::Autolock _l(mInvalidateLock);
17580dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    Region reg(mInvalidateRegion);
17590dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    mInvalidateRegion.clear();
17600dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    return reg;
17610dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian}
17620dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian
176359119e658a12279e8fff508f8773843de2d90917Mathias Agopian// ---------------------------------------------------------------------------
176459119e658a12279e8fff508f8773843de2d90917Mathias Agopian
1765118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopianstatus_t SurfaceFlinger::renderScreenToTexture(DisplayID dpy,
1766118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        GLuint* textureName, GLfloat* uOut, GLfloat* vOut)
1767118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{
1768118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    Mutex::Autolock _l(mStateLock);
1769118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    return renderScreenToTextureLocked(dpy, textureName, uOut, vOut);
1770118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
1771118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
17729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::renderScreenToTextureLocked(DisplayID dpy,
17739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        GLuint* textureName, GLfloat* uOut, GLfloat* vOut)
177459119e658a12279e8fff508f8773843de2d90917Mathias Agopian{
177559119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
177659119e658a12279e8fff508f8773843de2d90917Mathias Agopian        return INVALID_OPERATION;
177759119e658a12279e8fff508f8773843de2d90917Mathias Agopian
177859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // get screen geometry
177959119e658a12279e8fff508f8773843de2d90917Mathias Agopian    const DisplayHardware& hw(graphicPlane(dpy).displayHardware());
178059119e658a12279e8fff508f8773843de2d90917Mathias Agopian    const uint32_t hw_w = hw.getWidth();
178159119e658a12279e8fff508f8773843de2d90917Mathias Agopian    const uint32_t hw_h = hw.getHeight();
178259119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLfloat u = 1;
178359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLfloat v = 1;
178459119e658a12279e8fff508f8773843de2d90917Mathias Agopian
178559119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // make sure to clear all GL error flags
178659119e658a12279e8fff508f8773843de2d90917Mathias Agopian    while ( glGetError() != GL_NO_ERROR ) ;
178759119e658a12279e8fff508f8773843de2d90917Mathias Agopian
178859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // create a FBO
178959119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLuint name, tname;
179059119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glGenTextures(1, &tname);
179159119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
17929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
17939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            hw_w, hw_h, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
179459119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (glGetError() != GL_NO_ERROR) {
1795015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian        while ( glGetError() != GL_NO_ERROR ) ;
179659119e658a12279e8fff508f8773843de2d90917Mathias Agopian        GLint tw = (2 << (31 - clz(hw_w)));
179759119e658a12279e8fff508f8773843de2d90917Mathias Agopian        GLint th = (2 << (31 - clz(hw_h)));
17989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
17999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian                tw, th, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
180059119e658a12279e8fff508f8773843de2d90917Mathias Agopian        u = GLfloat(hw_w) / tw;
180159119e658a12279e8fff508f8773843de2d90917Mathias Agopian        v = GLfloat(hw_h) / th;
180259119e658a12279e8fff508f8773843de2d90917Mathias Agopian    }
180359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glGenFramebuffersOES(1, &name);
180459119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
18059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES,
18069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0);
180759119e658a12279e8fff508f8773843de2d90917Mathias Agopian
18089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // redraw the screen entirely...
1809c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_EXTERNAL_OES);
1810c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_2D);
181162f7114719d2009dca7dd120f0fe29a24bd77a40Mathias Agopian    glDisable(GL_SCISSOR_TEST);
18129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glClearColor(0,0,0,1);
18139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glClear(GL_COLOR_BUFFER_BIT);
181462f7114719d2009dca7dd120f0fe29a24bd77a40Mathias Agopian    glEnable(GL_SCISSOR_TEST);
1815a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glMatrixMode(GL_MODELVIEW);
1816a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glLoadIdentity();
18179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
18189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const size_t count = layers.size();
18199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (size_t i=0 ; i<count ; ++i) {
18209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
18219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        layer->drawForSreenShot();
18229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
182359119e658a12279e8fff508f8773843de2d90917Mathias Agopian
1824118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    hw.compositionComplete();
1825118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
18269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // back to main framebuffer
18279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
18289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_SCISSOR_TEST);
18299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDeleteFramebuffersOES(1, &name);
183059119e658a12279e8fff508f8773843de2d90917Mathias Agopian
18319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *textureName = tname;
18329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *uOut = u;
18339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *vOut = v;
18349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
18359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
183659119e658a12279e8fff508f8773843de2d90917Mathias Agopian
18379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// ---------------------------------------------------------------------------
183859119e658a12279e8fff508f8773843de2d90917Mathias Agopian
18399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::electronBeamOffAnimationImplLocked()
18409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
18419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // get screen geometry
18429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
18439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_w = hw.getWidth();
18449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_h = hw.getHeight();
1845a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    const Region screenBounds(hw.getBounds());
184659119e658a12279e8fff508f8773843de2d90917Mathias Agopian
18479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat u, v;
18489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLuint tname;
1849118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    status_t result = renderScreenToTextureLocked(0, &tname, &u, &v);
18509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (result != NO_ERROR) {
18519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return result;
18529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
185359119e658a12279e8fff508f8773843de2d90917Mathias Agopian
18549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat vtx[8];
1855a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    const GLfloat texCoords[4][2] = { {0,0}, {0,v}, {u,v}, {u,0} };
18569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
18579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
18589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
18599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
18609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
18619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
18629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glVertexPointer(2, GL_FLOAT, 0, vtx);
18639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
1864ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    /*
1865ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     * Texture coordinate mapping
1866ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *
1867ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *                 u
1868ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *    1 +----------+---+
1869ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |     |    |   |  image is inverted
1870ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |     V    |   |  w.r.t. the texture
1871ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *  1-v +----------+   |  coordinates
1872ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |              |
1873ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |              |
1874ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |              |
1875ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *    0 +--------------+
1876ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      0              1
1877ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *
1878ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     */
1879ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian
18809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class s_curve_interpolator {
18819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float nbFrames, s, v;
18829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
18839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        s_curve_interpolator(int nbFrames, float s)
18849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : nbFrames(1.0f / (nbFrames-1)), s(s),
18859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian          v(1.0f + expf(-s + 0.5f*s)) {
18869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
18879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float operator()(int f) {
18889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const float x = f * nbFrames;
18899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f;
18909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
18919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
18929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
18939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class v_stretch {
18949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
18959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
18969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        v_stretch(uint32_t hw_w, uint32_t hw_h)
18979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
18989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
18999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
19009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w + (hw_w * v);
19019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = hw_h - (hw_h * v);
19029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
19039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
1904ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[0] = x;         vtx[1] = y;
1905ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
1906ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
1907ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
19089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
19099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
19109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class h_stretch {
19129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
19139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
19149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        h_stretch(uint32_t hw_w, uint32_t hw_h)
19159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
191659119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
19179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
19189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w - (hw_w * v);
19199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = 1.0f;
19209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
19219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
1922ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[0] = x;         vtx[1] = y;
1923ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
1924ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
1925ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
19269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
19279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
19289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // the full animation is 24 frames
1930ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    char value[PROPERTY_VALUE_MAX];
1931ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    property_get("debug.sf.electron_frames", value, "24");
1932ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    int nbFrames = (atoi(value) + 1) >> 1;
1933ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    if (nbFrames <= 0) // just in case
1934ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian        nbFrames = 24;
1935ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian
19369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itr(nbFrames, 7.5f);
19379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itg(nbFrames, 8.0f);
19389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itb(nbFrames, 8.5f);
19399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    v_stretch vverts(hw_w, hw_h);
1941a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian
1942a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glMatrixMode(GL_TEXTURE);
1943a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glLoadIdentity();
1944a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glMatrixMode(GL_MODELVIEW);
1945a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glLoadIdentity();
1946a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian
19479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnable(GL_BLEND);
19489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBlendFunc(GL_ONE, GL_ONE);
19499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=0 ; i<nbFrames ; i++) {
19509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float x, y, w, h;
19519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vr = itr(i);
19529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vg = itg(i);
19539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vb = itb(i);
19549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // clear screen
19569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(1,1,1,1);
19579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
19589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glEnable(GL_TEXTURE_2D);
195959119e658a12279e8fff508f8773843de2d90917Mathias Agopian
19609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the red plane
19619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vr);
19629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(1,0,0,1);
19639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
19649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the green plane
19669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vg);
19679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,1,0,1);
19689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
19699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the blue plane
19719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vb);
19729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,0,1,1);
19739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
19749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the white highlight (we use the last vertices)
197659119e658a12279e8fff508f8773843de2d90917Mathias Agopian        glDisable(GL_TEXTURE_2D);
197759119e658a12279e8fff508f8773843de2d90917Mathias Agopian        glColorMask(1,1,1,1);
19789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColor4f(vg, vg, vg, 1);
19799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
19809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
19819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
19829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    h_stretch hverts(hw_w, hw_h);
19849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_BLEND);
19859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_TEXTURE_2D);
19869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
19879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=0 ; i<nbFrames ; i++) {
19889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float v = itg(i);
19899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hverts(vtx, v);
19909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
19919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColor4f(1-v, 1-v, 1-v, 1);
19929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
19939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
19949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
19959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
19979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnable(GL_SCISSOR_TEST);
19989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
19999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDeleteTextures(1, &tname);
2000a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    glDisable(GL_TEXTURE_2D);
2001c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_BLEND);
20029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
20039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
20049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::electronBeamOnAnimationImplLocked()
20069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
20079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    status_t result = PERMISSION_DENIED;
20089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
20109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return INVALID_OPERATION;
20119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // get screen geometry
20149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
20159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_w = hw.getWidth();
20169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_h = hw.getHeight();
20179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const Region screenBounds(hw.bounds());
20189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat u, v;
20209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLuint tname;
20219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    result = renderScreenToTextureLocked(0, &tname, &u, &v);
20229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (result != NO_ERROR) {
20239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return result;
20249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
20259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat vtx[8];
20279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const GLfloat texCoords[4][2] = { {0,v}, {0,0}, {u,0}, {u,v} };
20289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
20299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
20309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
20319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
20329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
20339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
20349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glVertexPointer(2, GL_FLOAT, 0, vtx);
20359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class s_curve_interpolator {
20379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float nbFrames, s, v;
20389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
20399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        s_curve_interpolator(int nbFrames, float s)
20409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : nbFrames(1.0f / (nbFrames-1)), s(s),
20419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian          v(1.0f + expf(-s + 0.5f*s)) {
20429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
20439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float operator()(int f) {
20449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const float x = f * nbFrames;
20459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f;
20469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
20479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
20489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class v_stretch {
20509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
20519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
20529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        v_stretch(uint32_t hw_w, uint32_t hw_h)
20539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
205459119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
20559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
20569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w + (hw_w * v);
20579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = hw_h - (hw_h * v);
20589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
20599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
20609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[0] = x;         vtx[1] = y;
20619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
20629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
20639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
20649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
20659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
20669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class h_stretch {
20689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
20699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
20709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        h_stretch(uint32_t hw_w, uint32_t hw_h)
20719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
20729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
20739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
20749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w - (hw_w * v);
20759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = 1.0f;
20769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
20779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
20789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[0] = x;         vtx[1] = y;
20799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
20809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
20819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
20829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
20839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
20849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2085a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian    // the full animation is 12 frames
2086a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian    int nbFrames = 8;
20879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itr(nbFrames, 7.5f);
20889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itg(nbFrames, 8.0f);
20899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itb(nbFrames, 8.5f);
20909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    h_stretch hverts(hw_w, hw_h);
20929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_BLEND);
20939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_TEXTURE_2D);
20949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
20959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=nbFrames-1 ; i>=0 ; i--) {
20969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float v = itg(i);
20979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hverts(vtx, v);
20989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
20999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColor4f(1-v, 1-v, 1-v, 1);
21009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
21019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
21029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
21039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2104a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian    nbFrames = 4;
21059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    v_stretch vverts(hw_w, hw_h);
21069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnable(GL_BLEND);
21079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBlendFunc(GL_ONE, GL_ONE);
21089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=nbFrames-1 ; i>=0 ; i--) {
21099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float x, y, w, h;
21109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vr = itr(i);
21119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vg = itg(i);
21129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vb = itb(i);
211359119e658a12279e8fff508f8773843de2d90917Mathias Agopian
21149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // clear screen
211559119e658a12279e8fff508f8773843de2d90917Mathias Agopian        glColorMask(1,1,1,1);
21169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
21179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glEnable(GL_TEXTURE_2D);
21189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the red plane
21209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vr);
21219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(1,0,0,1);
21229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
21239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the green plane
21259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vg);
21269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,1,0,1);
21279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
21289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the blue plane
21309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vb);
21319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,0,1,1);
21329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
21339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
213559119e658a12279e8fff508f8773843de2d90917Mathias Agopian    }
213659119e658a12279e8fff508f8773843de2d90917Mathias Agopian
21379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
21389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnable(GL_SCISSOR_TEST);
21399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
214059119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glDeleteTextures(1, &tname);
2141a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    glDisable(GL_TEXTURE_2D);
2142c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_BLEND);
214359119e658a12279e8fff508f8773843de2d90917Mathias Agopian
21449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
21459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
21469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// ---------------------------------------------------------------------------
21489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2149abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOffImplLocked(int32_t mode)
21509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
21519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    DisplayHardware& hw(graphicPlane(0).editDisplayHardware());
21529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (!hw.canDraw()) {
21539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // we're already off
21549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return NO_ERROR;
21559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
21567ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian
21577ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian    // turn off hwc while we're doing the animation
21587ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian    hw.getHwComposer().disable();
21597ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian    // and make sure to turn it back on (if needed) next time we compose
21607ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian    invalidateHwcGeometry();
21617ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian
2162abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    if (mode & ISurfaceComposer::eElectronBeamAnimationOff) {
2163abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        electronBeamOffAnimationImplLocked();
2164abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    }
2165abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian
2166abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    // always clear the whole screen at the end of the animation
2167abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    glClearColor(0,0,0,1);
2168abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    glDisable(GL_SCISSOR_TEST);
2169abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    glClear(GL_COLOR_BUFFER_BIT);
2170abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    glEnable(GL_SCISSOR_TEST);
2171abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    hw.flip( Region(hw.bounds()) );
2172abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian
2173015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian    return NO_ERROR;
217459119e658a12279e8fff508f8773843de2d90917Mathias Agopian}
217559119e658a12279e8fff508f8773843de2d90917Mathias Agopian
217659119e658a12279e8fff508f8773843de2d90917Mathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOff(int32_t mode)
217759119e658a12279e8fff508f8773843de2d90917Mathias Agopian{
217859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    class MessageTurnElectronBeamOff : public MessageBase {
217959119e658a12279e8fff508f8773843de2d90917Mathias Agopian        SurfaceFlinger* flinger;
2180abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        int32_t mode;
218159119e658a12279e8fff508f8773843de2d90917Mathias Agopian        status_t result;
218259119e658a12279e8fff508f8773843de2d90917Mathias Agopian    public:
2183abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        MessageTurnElectronBeamOff(SurfaceFlinger* flinger, int32_t mode)
2184abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            : flinger(flinger), mode(mode), result(PERMISSION_DENIED) {
218559119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
218659119e658a12279e8fff508f8773843de2d90917Mathias Agopian        status_t getResult() const {
218759119e658a12279e8fff508f8773843de2d90917Mathias Agopian            return result;
218859119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
218959119e658a12279e8fff508f8773843de2d90917Mathias Agopian        virtual bool handler() {
219059119e658a12279e8fff508f8773843de2d90917Mathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
2191abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            result = flinger->turnElectronBeamOffImplLocked(mode);
219259119e658a12279e8fff508f8773843de2d90917Mathias Agopian            return true;
219359119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
219459119e658a12279e8fff508f8773843de2d90917Mathias Agopian    };
219559119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2196abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    sp<MessageBase> msg = new MessageTurnElectronBeamOff(this, mode);
219759119e658a12279e8fff508f8773843de2d90917Mathias Agopian    status_t res = postMessageSync(msg);
219859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (res == NO_ERROR) {
219959119e658a12279e8fff508f8773843de2d90917Mathias Agopian        res = static_cast<MessageTurnElectronBeamOff*>( msg.get() )->getResult();
22009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // work-around: when the power-manager calls us we activate the
22029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // animation. eventually, the "on" animation will be called
22039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // by the power-manager itself
2204abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        mElectronBeamAnimationMode = mode;
220559119e658a12279e8fff508f8773843de2d90917Mathias Agopian    }
220659119e658a12279e8fff508f8773843de2d90917Mathias Agopian    return res;
220759119e658a12279e8fff508f8773843de2d90917Mathias Agopian}
220859119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2209edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
2210edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2211abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOnImplLocked(int32_t mode)
22129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
22139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    DisplayHardware& hw(graphicPlane(0).editDisplayHardware());
22149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (hw.canDraw()) {
22159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // we're already on
22169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return NO_ERROR;
22179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
2218abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    if (mode & ISurfaceComposer::eElectronBeamAnimationOn) {
2219abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        electronBeamOnAnimationImplLocked();
2220abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    }
2221a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian
2222a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian    // make sure to redraw the whole screen when the animation is done
2223a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian    mDirtyRegion.set(hw.bounds());
2224a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian    signalEvent();
2225a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian
2226015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian    return NO_ERROR;
22279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
22289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOn(int32_t mode)
22309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
22319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class MessageTurnElectronBeamOn : public MessageBase {
22329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        SurfaceFlinger* flinger;
2233abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        int32_t mode;
22349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        status_t result;
22359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
2236abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        MessageTurnElectronBeamOn(SurfaceFlinger* flinger, int32_t mode)
2237abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            : flinger(flinger), mode(mode), result(PERMISSION_DENIED) {
22389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
22399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        status_t getResult() const {
22409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return result;
22419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
22429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        virtual bool handler() {
22439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
2244abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            result = flinger->turnElectronBeamOnImplLocked(mode);
22459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return true;
22469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
22479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
22489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2249abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    postMessageAsync( new MessageTurnElectronBeamOn(this, mode) );
22509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
22519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
22529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// ---------------------------------------------------------------------------
22549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
225574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopianstatus_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy,
225674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        sp<IMemoryHeap>* heap,
225774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t* w, uint32_t* h, PixelFormat* f,
2258bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t sw, uint32_t sh,
2259bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ, uint32_t maxLayerZ)
226074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{
226174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    status_t result = PERMISSION_DENIED;
226274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
226374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // only one display supported for now
226499ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten    if (CC_UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
226574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return BAD_VALUE;
226674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
226774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
226874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return INVALID_OPERATION;
226974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
227074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // get screen geometry
227174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const DisplayHardware& hw(graphicPlane(dpy).displayHardware());
227274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const uint32_t hw_w = hw.getWidth();
227374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const uint32_t hw_h = hw.getHeight();
227474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
227574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    if ((sw > hw_w) || (sh > hw_h))
227674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return BAD_VALUE;
227774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
227874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    sw = (!sw) ? hw_w : sw;
227974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    sh = (!sh) ? hw_h : sh;
228074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const size_t size = sw * sh * 4;
228174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
22829d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block    //ALOGD("screenshot: sw=%d, sh=%d, minZ=%d, maxZ=%d",
22831c71a47a6db679a3212f0c99e14f330d6da500faMathias Agopian    //        sw, sh, minLayerZ, maxLayerZ);
2284c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
228574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // make sure to clear all GL error flags
228674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    while ( glGetError() != GL_NO_ERROR ) ;
228774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
228874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // create a FBO
228974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    GLuint name, tname;
229074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glGenRenderbuffersOES(1, &tname);
229174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindRenderbufferOES(GL_RENDERBUFFER_OES, tname);
229274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA8_OES, sw, sh);
229374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glGenFramebuffersOES(1, &name);
229474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
229574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES,
229674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, tname);
229774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
229874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
2299c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
230074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    if (status == GL_FRAMEBUFFER_COMPLETE_OES) {
230174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
230274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // invert everything, b/c glReadPixel() below will invert the FB
230374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glViewport(0, 0, sw, sh);
2304f653b897a449e10d6cbfb6e0812f7b0bb02d6482Mathias Agopian        glScissor(0, 0, sw, sh);
2305ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian        glEnable(GL_SCISSOR_TEST);
230674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_PROJECTION);
230774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glPushMatrix();
230874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glLoadIdentity();
2309ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian        glOrthof(0, hw_w, hw_h, 0, 0, 1);
231074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_MODELVIEW);
231174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
231274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // redraw the screen entirely...
231374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glClearColor(0,0,0,1);
231474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
2315f653b897a449e10d6cbfb6e0812f7b0bb02d6482Mathias Agopian
23169575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        const LayerVector& layers(mDrawingState.layersSortedByZ);
23179575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        const size_t count = layers.size();
231874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        for (size_t i=0 ; i<count ; ++i) {
231974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            const sp<LayerBase>& layer(layers[i]);
2320b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian            const uint32_t flags = layer->drawingState().flags;
2321b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian            if (!(flags & ISurfaceComposer::eLayerHidden)) {
2322b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                const uint32_t z = layer->drawingState().z;
2323b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                if (z >= minLayerZ && z <= maxLayerZ) {
2324b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                    layer->drawForSreenShot();
2325b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                }
2326bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian            }
232774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        }
232874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
232974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // XXX: this is needed on tegra
2330ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian        glEnable(GL_SCISSOR_TEST);
233174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glScissor(0, 0, sw, sh);
233274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
233374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // check for errors and return screen capture
233474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        if (glGetError() != GL_NO_ERROR) {
233574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // error while rendering
233674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            result = INVALID_OPERATION;
233774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        } else {
233874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // allocate shared memory large enough to hold the
233974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // screen capture
234074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            sp<MemoryHeapBase> base(
234174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    new MemoryHeapBase(size, 0, "screen-capture") );
234274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            void* const ptr = base->getBase();
234374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            if (ptr) {
234474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                // capture the screen with glReadPixels()
234574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                glReadPixels(0, 0, sw, sh, GL_RGBA, GL_UNSIGNED_BYTE, ptr);
234674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                if (glGetError() == GL_NO_ERROR) {
234774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *heap = base;
234874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *w = sw;
234974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *h = sh;
235074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *f = PIXEL_FORMAT_RGBA_8888;
235174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    result = NO_ERROR;
235274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                }
235374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            } else {
235474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                result = NO_MEMORY;
235574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            }
235674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        }
235774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glEnable(GL_SCISSOR_TEST);
235874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glViewport(0, 0, hw_w, hw_h);
235974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_PROJECTION);
236074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glPopMatrix();
236174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_MODELVIEW);
236274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    } else {
236374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        result = BAD_VALUE;
236474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    }
236574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
236674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // release FBO resources
236774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
236874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glDeleteRenderbuffersOES(1, &tname);
236974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glDeleteFramebuffersOES(1, &name);
2370e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian
2371e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian    hw.compositionComplete();
2372e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian
23739d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block    // ALOGD("screenshot: result = %s", result<0 ? strerror(result) : "OK");
2374c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
237574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    return result;
237674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian}
237774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
237874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
23791b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopianstatus_t SurfaceFlinger::captureScreen(DisplayID dpy,
23801b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        sp<IMemoryHeap>* heap,
238174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t* width, uint32_t* height, PixelFormat* format,
2382bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t sw, uint32_t sh,
2383bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ, uint32_t maxLayerZ)
23841b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian{
23851b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    // only one display supported for now
238699ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten    if (CC_UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
23871b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        return BAD_VALUE;
23881b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
23891b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
23901b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        return INVALID_OPERATION;
23911b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
23921b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    class MessageCaptureScreen : public MessageBase {
23931b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        SurfaceFlinger* flinger;
23941b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        DisplayID dpy;
23951b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        sp<IMemoryHeap>* heap;
23961b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        uint32_t* w;
23971b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        uint32_t* h;
23981b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        PixelFormat* f;
239974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t sw;
240074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t sh;
2401bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ;
2402bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t maxLayerZ;
24031b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        status_t result;
24041b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    public:
24051b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        MessageCaptureScreen(SurfaceFlinger* flinger, DisplayID dpy,
240674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                sp<IMemoryHeap>* heap, uint32_t* w, uint32_t* h, PixelFormat* f,
2407bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                uint32_t sw, uint32_t sh,
2408bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                uint32_t minLayerZ, uint32_t maxLayerZ)
24091b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            : flinger(flinger), dpy(dpy),
2410bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              heap(heap), w(w), h(h), f(f), sw(sw), sh(sh),
2411bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              minLayerZ(minLayerZ), maxLayerZ(maxLayerZ),
2412bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              result(PERMISSION_DENIED)
24131b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
24141b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
24151b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        status_t getResult() const {
24161b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            return result;
24171b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
24181b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        virtual bool handler() {
24191b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
24201b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
24211b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            // if we have secure windows, never allow the screen capture
24221b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            if (flinger->mSecureFrameBuffer)
24231b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                return true;
24241b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
242574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            result = flinger->captureScreenImplLocked(dpy,
2426bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                    heap, w, h, f, sw, sh, minLayerZ, maxLayerZ);
24271b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
24281b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            return true;
24291b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
24301b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    };
24311b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
24321b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    sp<MessageBase> msg = new MessageCaptureScreen(this,
2433bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian            dpy, heap, width, height, format, sw, sh, minLayerZ, maxLayerZ);
24341b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    status_t res = postMessageSync(msg);
24351b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    if (res == NO_ERROR) {
24361b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        res = static_cast<MessageCaptureScreen*>( msg.get() )->getResult();
24371b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    }
24381b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    return res;
24391b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian}
24401b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
24411b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// ---------------------------------------------------------------------------
24421b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
2443b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<Layer> SurfaceFlinger::getLayer(const sp<ISurface>& sur) const
2444edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2445b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<Layer> result;
2446b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    Mutex::Autolock _l(mStateLock);
2447b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    result = mLayerMap.valueFor( sur->asBinder() ).promote();
2448b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return result;
2449b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
24507303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
2451b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// ---------------------------------------------------------------------------
245296f0819f81293076e652792794a961543e6750d7Mathias Agopian
2453b7e930db175c192464cebdeb49eb56cf6dd60114Mathias AgopianClient::Client(const sp<SurfaceFlinger>& flinger)
2454b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    : mFlinger(flinger), mNameGenerator(1)
2455b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{
2456edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2457edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
245896f0819f81293076e652792794a961543e6750d7Mathias AgopianClient::~Client()
245996f0819f81293076e652792794a961543e6750d7Mathias Agopian{
246096f0819f81293076e652792794a961543e6750d7Mathias Agopian    const size_t count = mLayers.size();
246196f0819f81293076e652792794a961543e6750d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
246296f0819f81293076e652792794a961543e6750d7Mathias Agopian        sp<LayerBaseClient> layer(mLayers.valueAt(i).promote());
246396f0819f81293076e652792794a961543e6750d7Mathias Agopian        if (layer != 0) {
246496f0819f81293076e652792794a961543e6750d7Mathias Agopian            mFlinger->removeLayer(layer);
246596f0819f81293076e652792794a961543e6750d7Mathias Agopian        }
2466edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2467edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2468076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
246996f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t Client::initCheck() const {
2470b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return NO_ERROR;
2471edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2472076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
24734f113740180b6512b43723c4728f262882dc9b45Mathias Agopiansize_t Client::attachLayer(const sp<LayerBaseClient>& layer)
2474edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
24754f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    Mutex::Autolock _l(mLock);
24764f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    size_t name = mNameGenerator++;
247796f0819f81293076e652792794a961543e6750d7Mathias Agopian    mLayers.add(name, layer);
247896f0819f81293076e652792794a961543e6750d7Mathias Agopian    return name;
2479edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2480edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2481b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianvoid Client::detachLayer(const LayerBaseClient* layer)
248296f0819f81293076e652792794a961543e6750d7Mathias Agopian{
24834f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    Mutex::Autolock _l(mLock);
248496f0819f81293076e652792794a961543e6750d7Mathias Agopian    // we do a linear search here, because this doesn't happen often
248596f0819f81293076e652792794a961543e6750d7Mathias Agopian    const size_t count = mLayers.size();
248696f0819f81293076e652792794a961543e6750d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
248796f0819f81293076e652792794a961543e6750d7Mathias Agopian        if (mLayers.valueAt(i) == layer) {
248896f0819f81293076e652792794a961543e6750d7Mathias Agopian            mLayers.removeItemsAt(i, 1);
248996f0819f81293076e652792794a961543e6750d7Mathias Agopian            break;
249096f0819f81293076e652792794a961543e6750d7Mathias Agopian        }
249196f0819f81293076e652792794a961543e6750d7Mathias Agopian    }
249296f0819f81293076e652792794a961543e6750d7Mathias Agopian}
24934f113740180b6512b43723c4728f262882dc9b45Mathias Agopiansp<LayerBaseClient> Client::getLayerUser(int32_t i) const
24944f113740180b6512b43723c4728f262882dc9b45Mathias Agopian{
24954f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    Mutex::Autolock _l(mLock);
2496076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBaseClient> lbc;
24974f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    wp<LayerBaseClient> layer(mLayers.valueFor(i));
249896f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (layer != 0) {
249996f0819f81293076e652792794a961543e6750d7Mathias Agopian        lbc = layer.promote();
2500e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE_IF(lbc==0, "getLayerUser(name=%d) is dead", int(i));
2501076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
2502076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return lbc;
2503edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2504edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2505a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
2506a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianstatus_t Client::onTransact(
2507a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
2508a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian{
2509a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // these must be checked
2510a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     IPCThreadState* ipc = IPCThreadState::self();
2511a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     const int pid = ipc->getCallingPid();
2512a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     const int uid = ipc->getCallingUid();
2513a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     const int self_pid = getpid();
251499ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten     if (CC_UNLIKELY(pid != self_pid && uid != AID_GRAPHICS && uid != 0)) {
2515a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian         // we're called from a different process, do the real check
251699b49840d309727678b77403d6cc9f920111623fMathias Agopian         if (!PermissionCache::checkCallingPermission(sAccessSurfaceFlinger))
2517a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian         {
2518e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block             ALOGE("Permission Denial: "
2519a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                     "can't openGlobalTransaction pid=%d, uid=%d", pid, uid);
2520a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian             return PERMISSION_DENIED;
2521a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian         }
2522a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     }
2523a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     return BnSurfaceComposerClient::onTransact(code, data, reply, flags);
2524edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2525a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
2526a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
252796f0819f81293076e652792794a961543e6750d7Mathias Agopiansp<ISurface> Client::createSurface(
25280ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        ISurfaceComposerClient::surface_data_t* params,
2529b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        const String8& name,
2530b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
2531edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t flags)
2532edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2533b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    /*
2534a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     * createSurface must be called from the GL thread so that it can
2535a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     * have access to the GL context.
2536b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     */
2537b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
2538a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    class MessageCreateSurface : public MessageBase {
2539a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        sp<ISurface> result;
2540a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        SurfaceFlinger* flinger;
2541a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        ISurfaceComposerClient::surface_data_t* params;
2542a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        Client* client;
2543a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        const String8& name;
2544a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        DisplayID display;
2545a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        uint32_t w, h;
2546a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        PixelFormat format;
2547a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        uint32_t flags;
2548a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    public:
2549a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        MessageCreateSurface(SurfaceFlinger* flinger,
2550a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                ISurfaceComposerClient::surface_data_t* params,
2551a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                const String8& name, Client* client,
2552a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
2553a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                uint32_t flags)
2554a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            : flinger(flinger), params(params), client(client), name(name),
2555a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian              display(display), w(w), h(h), format(format), flags(flags)
2556a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        {
2557579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        }
2558a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        sp<ISurface> getResult() const { return result; }
2559a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        virtual bool handler() {
2560a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            result = flinger->createSurface(params, name, client,
2561a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                    display, w, h, format, flags);
2562a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            return true;
2563b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        }
2564a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    };
2565b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
2566a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    sp<MessageBase> msg = new MessageCreateSurface(mFlinger.get(),
2567a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            params, name, this, display, w, h, format, flags);
2568a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    mFlinger->postMessageSync(msg);
2569a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    return static_cast<MessageCreateSurface*>( msg.get() )->getResult();
2570b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
2571a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianstatus_t Client::destroySurface(SurfaceID sid) {
2572a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    return mFlinger->removeSurface(this, sid);
2573b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
2574b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
2575b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// ---------------------------------------------------------------------------
2576edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
25779a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::GraphicBufferAlloc() {}
25789a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
25799a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::~GraphicBufferAlloc() {}
25809a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
25819a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h,
2582d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        PixelFormat format, uint32_t usage, status_t* error) {
25839a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(w, h, format, usage));
25849a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    status_t err = graphicBuffer->initCheck();
2585d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian    *error = err;
2586a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (err != 0 || graphicBuffer->handle == 0) {
2587d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        if (err == NO_MEMORY) {
2588d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian            GraphicBuffer::dumpAllocationsToSystemLog();
2589d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        }
2590e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE("GraphicBufferAlloc::createGraphicBuffer(w=%d, h=%d) "
2591a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian             "failed (%s), handle=%p",
2592a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                w, h, strerror(-err), graphicBuffer->handle);
25939a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis        return 0;
25949a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    }
25959a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    return graphicBuffer;
25969a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis}
25979a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
25989a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis// ---------------------------------------------------------------------------
25999a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
2600edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane::GraphicPlane()
2601edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    : mHw(0)
2602edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2603edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2604edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2605edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane::~GraphicPlane() {
2606edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    delete mHw;
2607edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2608edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2609edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool GraphicPlane::initialized() const {
2610edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return mHw ? true : false;
2611edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2612edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
26132b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianint GraphicPlane::getWidth() const {
26142b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    return mWidth;
2615edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2616edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
26172b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianint GraphicPlane::getHeight() const {
26182b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    return mHeight;
26192b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian}
26202b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
26212b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianvoid GraphicPlane::setDisplayHardware(DisplayHardware *hw)
26222b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian{
26232b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mHw = hw;
26242b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
26252b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    // initialize the display orientation transform.
26262b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    // it's a constant that should come from the display driver.
26272b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    int displayOrientation = ISurfaceComposer::eOrientationDefault;
26282b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    char property[PROPERTY_VALUE_MAX];
26292b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    if (property_get("ro.sf.hwrotation", property, NULL) > 0) {
26302b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        //displayOrientation
26312b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        switch (atoi(property)) {
26322b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        case 90:
26332b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            displayOrientation = ISurfaceComposer::eOrientation90;
26342b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            break;
26352b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        case 270:
26362b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            displayOrientation = ISurfaceComposer::eOrientation270;
26372b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            break;
26382b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        }
26392b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    }
26402b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
26412b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float w = hw->getWidth();
26422b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float h = hw->getHeight();
26432b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    GraphicPlane::orientationToTransfrom(displayOrientation, w, h,
26442b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            &mDisplayTransform);
26452b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    if (displayOrientation & ISurfaceComposer::eOrientationSwapMask) {
26462b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayWidth = h;
26472b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayHeight = w;
26482b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    } else {
26492b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayWidth = w;
26502b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayHeight = h;
26512b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    }
26522b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
26532b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    setOrientation(ISurfaceComposer::eOrientationDefault);
2654edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2655edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2656edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t GraphicPlane::orientationToTransfrom(
2657edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int orientation, int w, int h, Transform* tr)
2658eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian{
2659eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    uint32_t flags = 0;
2660edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (orientation) {
2661edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientationDefault:
2662eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_0;
2663eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        break;
2664edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientation90:
2665eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_90;
2666edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
2667edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientation180:
2668eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_180;
2669edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
2670edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientation270:
2671eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_270;
2672edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
2673edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    default:
2674edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return BAD_VALUE;
2675edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2676eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    tr->set(flags, w, h);
2677edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
2678edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2679edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2680edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t GraphicPlane::setOrientation(int orientation)
2681edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2682edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // If the rotation can be handled in hardware, this is where
2683edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // the magic should happen.
26842b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
26852b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const DisplayHardware& hw(displayHardware());
26862b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float w = mDisplayWidth;
26872b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float h = mDisplayHeight;
26882b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mWidth = int(w);
26892b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mHeight = int(h);
26902b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
26912b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    Transform orientationTransform;
2692eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    GraphicPlane::orientationToTransfrom(orientation, w, h,
2693eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian            &orientationTransform);
2694eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    if (orientation & ISurfaceComposer::eOrientationSwapMask) {
2695eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        mWidth = int(h);
2696eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        mHeight = int(w);
2697edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2698eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian
26990d1318b974feba2e6ff13e36a1781343c2fce045Mathias Agopian    mOrientation = orientation;
27002b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mGlobalTransform = mDisplayTransform * orientationTransform;
2701edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
2702edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2703edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2704edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst DisplayHardware& GraphicPlane::displayHardware() const {
2705edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return *mHw;
2706edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2707edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
270859119e658a12279e8fff508f8773843de2d90917Mathias AgopianDisplayHardware& GraphicPlane::editDisplayHardware() {
270959119e658a12279e8fff508f8773843de2d90917Mathias Agopian    return *mHw;
271059119e658a12279e8fff508f8773843de2d90917Mathias Agopian}
271159119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2712edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst Transform& GraphicPlane::transform() const {
2713edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return mGlobalTransform;
2714edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2715edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2716076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias AgopianEGLDisplay GraphicPlane::getEGLDisplay() const {
2717076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return mHw->getEGLDisplay();
2718076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
2719076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
2720edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
2721edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2722edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
2723