SurfaceFlinger.cpp revision b0610335d745718f5ee54f15ef1a492921d759f4
1edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/*
2edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
3edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
4edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * you may not use this file except in compliance with the License.
6edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * You may obtain a copy of the License at
7edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
8edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
10edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * See the License for the specific language governing permissions and
14edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * limitations under the License.
15edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */
16edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
17edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdlib.h>
18edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdio.h>
19edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdint.h>
20edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <unistd.h>
21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <fcntl.h>
22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <errno.h>
23edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <math.h>
24a837ba778f2d7a5170b37aa33624d9b9711c354dJean-Baptiste Queru#include <limits.h>
25edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/types.h>
26edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/stat.h>
27edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/ioctl.h>
28edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/log.h>
30edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/properties.h>
31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
32c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IPCThreadState.h>
33c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IServiceManager.h>
347303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian#include <binder/MemoryHeapBase.h>
3599b49840d309727678b77403d6cc9f920111623fMathias Agopian#include <binder/PermissionCache.h>
367303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
37edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String8.h>
38edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String16.h>
39edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/StopWatch.h>
40edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
413330b203039dea366d4981db1408a460134b2d2cMathias Agopian#include <ui/GraphicBufferAllocator.h>
4235b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian#include <ui/GraphicLog.h>
43edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/PixelFormat.h>
44edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <pixelflinger/pixelflinger.h>
46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <GLES/gl.h>
47edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
48edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h"
491f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian#include "GLExtensions.h"
508afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian#include "DdmConnection.h"
51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h"
52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerDim.h"
53edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h"
54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
55edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "DisplayHardware/DisplayHardware.h"
56a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian#include "DisplayHardware/HWComposer.h"
57edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
58a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian#include <private/surfaceflinger/SharedBufferStack.h>
59a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
60a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian/* ideally AID_GRAPHICS would be in a semi-public header
61a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian * or there would be a way to map a user/group name to its id
62a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian */
63a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian#ifndef AID_GRAPHICS
64a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian#define AID_GRAPHICS 1003
65a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian#endif
66a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian
67edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DISPLAY_COUNT       1
68edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
7299b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sHardwareTest("android.permission.HARDWARE_TEST");
7399b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER");
7499b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER");
7599b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sDump("android.permission.DUMP");
7699b49840d309727678b77403d6cc9f920111623fMathias Agopian
7799b49840d309727678b77403d6cc9f920111623fMathias Agopian// ---------------------------------------------------------------------------
7899b49840d309727678b77403d6cc9f920111623fMathias Agopian
79edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::SurfaceFlinger()
80edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    :   BnSurfaceComposer(), Thread(false),
81edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mTransactionFlags(0),
82cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        mResizeTransationPending(false),
83076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved(false),
84edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mBootTime(systemTime()),
85edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mVisibleRegionsDirty(false),
86a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        mHwWorkListDirty(false),
87edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDeferReleaseConsole(false),
88edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mFreezeDisplay(false),
89abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        mElectronBeamAnimationMode(0),
90edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mFreezeCount(0),
91bcef13b666c7459241235bc6209837ae81884d2fThe Android Open Source Project        mFreezeDisplayTime(0),
92edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDebugRegion(0),
93edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDebugBackground(0),
948afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian        mDebugDDMS(0),
9573d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian        mDebugDisableHWC(0),
96a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian        mDebugDisableTransformHint(0),
979795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInSwapBuffers(0),
989795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastSwapBufferTime(0),
999795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInTransaction(0),
1009795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastTransactionTime(0),
1013330b203039dea366d4981db1408a460134b2d2cMathias Agopian        mBootFinished(false),
102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mConsoleSignals(0),
103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mSecureFrameBuffer(0)
104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    init();
106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::init()
109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    LOGI("SurfaceFlinger is starting");
111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // debugging stuff...
113edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char value[PROPERTY_VALUE_MAX];
1148afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    property_get("debug.sf.showupdates", value, "0");
116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDebugRegion = atoi(value);
1178afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    property_get("debug.sf.showbackground", value, "0");
119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDebugBackground = atoi(value);
120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1218afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    property_get("debug.sf.ddms", value, "0");
1228afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    mDebugDDMS = atoi(value);
1238afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    if (mDebugDDMS) {
1248afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian        DdmConnection::start(getServiceName());
1258afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    }
1268afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
12778fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian    LOGI_IF(mDebugRegion,       "showupdates enabled");
12878fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian    LOGI_IF(mDebugBackground,   "showbackground enabled");
1298afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    LOGI_IF(mDebugDDMS,         "DDMS debugging enabled");
130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::~SurfaceFlinger()
133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDeleteTextures(1, &mWormholeTexName);
135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1377303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopiansp<IMemoryHeap> SurfaceFlinger::getCblk() const
138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1397303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    return mServerHeap;
140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
141edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1427e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopiansp<ISurfaceComposerClient> SurfaceFlinger::createConnection()
143edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
14496f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<ISurfaceComposerClient> bclient;
14596f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<Client> client(new Client(this));
14696f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = client->initCheck();
14796f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR) {
14896f0819f81293076e652792794a961543e6750d7Mathias Agopian        bclient = client;
149edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
150edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return bclient;
151edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
152edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1539a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc()
1549a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis{
1559a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc());
1569a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    return gba;
1579a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis}
158b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst GraphicPlane& SurfaceFlinger::graphicPlane(int dpy) const
160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    LOGE_IF(uint32_t(dpy) >= DISPLAY_COUNT, "Invalid DisplayID %d", dpy);
162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(mGraphicPlanes[dpy]);
163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return plane;
164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane& SurfaceFlinger::graphicPlane(int dpy)
167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return const_cast<GraphicPlane&>(
169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const_cast<SurfaceFlinger const *>(this)->graphicPlane(dpy));
170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::bootFinished()
173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t now = systemTime();
175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t duration = now - mBootTime;
1768b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber    LOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
1773330b203039dea366d4981db1408a460134b2d2cMathias Agopian    mBootFinished = true;
1781f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
1791f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // wait patiently for the window manager death
1801f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    const String16 name("window");
1811f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    sp<IBinder> window(defaultServiceManager()->getService(name));
1821f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    if (window != 0) {
1831f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian        window->linkToDeath(this);
1841f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    }
1851f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
1861f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // stop boot animation
187a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    property_set("ctl.stop", "bootanim");
188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1901f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopianvoid SurfaceFlinger::binderDied(const wp<IBinder>& who)
1911f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian{
1921f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // the window manager died on us. prepare its eulogy.
1931f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
1941f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // unfreeze the screen in case it was... frozen
1951f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    mFreezeDisplayTime = 0;
1961f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    mFreezeCount = 0;
1971f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    mFreezeDisplay = false;
1981f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
1991f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // reset screen orientation
2001f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    setOrientation(0, eOrientationDefault, 0);
2011f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
2021f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // restart the boot-animation
2031f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    property_set("ctl.start", "bootanim");
2041f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian}
2051f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
206edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::onFirstRef()
207edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY);
209edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
210edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // Wait for the main thread to be done with its initialization
211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mReadyToRunBarrier.wait();
212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic inline uint16_t pack565(int r, int g, int b) {
215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return (r<<11)|(g<<5)|b;
216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
217edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::readyToRun()
219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    LOGI(   "SurfaceFlinger's main thread ready to run. "
221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            "Initializing graphics H/W...");
222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // we only support one display currently
224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int dpy = 0;
225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    {
227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // initialize the main display
228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GraphicPlane& plane(graphicPlane(dpy));
229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        DisplayHardware* const hw = new DisplayHardware(this, dpy);
230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        plane.setDisplayHardware(hw);
231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2337303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    // create the shared control-block
2347303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    mServerHeap = new MemoryHeapBase(4096,
2357303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian            MemoryHeapBase::READ_ONLY, "SurfaceFlinger read-only heap");
2367303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    LOGE_IF(mServerHeap==0, "can't create shared memory dealer");
2378b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
2387303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    mServerCblk = static_cast<surface_flinger_cblk_t*>(mServerHeap->getBase());
2397303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    LOGE_IF(mServerCblk==0, "can't get to shared control block's address");
2408b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
2417303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    new(mServerCblk) surface_flinger_cblk_t;
2427303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize primary screen
244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // (other display should be initialized in the same manner, but
245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // asynchronously, as they could come and go. None of this is supported
246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // yet).
247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(graphicPlane(dpy));
248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw = plane.displayHardware();
249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint32_t w = hw.getWidth();
250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint32_t h = hw.getHeight();
251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint32_t f = hw.getFormat();
252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    hw.makeCurrent();
253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize the shared control block
255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mServerCblk->connected |= 1<<dpy;
256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    display_cblk_t* dcblk = mServerCblk->displays + dpy;
257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    memset(dcblk, 0, sizeof(display_cblk_t));
2582b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    dcblk->w            = plane.getWidth();
2592b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    dcblk->h            = plane.getHeight();
260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->format       = f;
261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->orientation  = ISurfaceComposer::eOrientationDefault;
262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->xdpi         = hw.getDpiX();
263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->ydpi         = hw.getDpiY();
264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->fps          = hw.getRefreshRate();
265edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->density      = hw.getDensity();
266edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
267edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // Initialize OpenGL|ES
268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
2698b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber    glPixelStorei(GL_PACK_ALIGNMENT, 4);
270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glEnableClientState(GL_VERTEX_ARRAY);
271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glEnable(GL_SCISSOR_TEST);
272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glShadeModel(GL_FLAT);
273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_DITHER);
274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_CULL_FACE);
275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint16_t g0 = pack565(0x0F,0x1F,0x0F);
277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint16_t g1 = pack565(0x17,0x2f,0x17);
278edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint16_t textureData[4] = { g0, g1, g1, g0 };
279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glGenTextures(1, &mWormholeTexName);
280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glBindTexture(GL_TEXTURE_2D, mWormholeTexName);
281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
284edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
285edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0,
286edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            GL_RGB, GL_UNSIGNED_SHORT_5_6_5, textureData);
287edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
288edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glViewport(0, 0, w, h);
289edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glMatrixMode(GL_PROJECTION);
290edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glLoadIdentity();
291ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    // put the origin in the left-bottom corner
292ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    glOrthof(0, w, 0, h, 0, 1); // l=0, r=w ; b=0, t=h
293edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
294edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mReadyToRunBarrier.open();
295edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     *  We're now ready to accept clients...
298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
300a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    // start boot animation
301a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    property_set("ctl.start", "bootanim");
3028b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if 0
308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark -
309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark Events Handler
310edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif
311edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
312edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::waitForEvent()
313edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
314f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    while (true) {
315f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        nsecs_t timeout = -1;
3160408772e34931351d062f2088b611325ddaa6cdbMathias Agopian        const nsecs_t freezeDisplayTimeout = ms2ns(5000);
317f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        if (UNLIKELY(isFrozen())) {
318f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            // wait 5 seconds
319f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            const nsecs_t now = systemTime();
320f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            if (mFreezeDisplayTime == 0) {
321f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian                mFreezeDisplayTime = now;
322f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            }
323f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            nsecs_t waitTime = freezeDisplayTimeout - (now - mFreezeDisplayTime);
324f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            timeout = waitTime>0 ? waitTime : 0;
325bcef13b666c7459241235bc6209837ae81884d2fThe Android Open Source Project        }
326f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian
327bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        sp<MessageBase> msg = mEventQueue.waitMessage(timeout);
3280408772e34931351d062f2088b611325ddaa6cdbMathias Agopian
3290408772e34931351d062f2088b611325ddaa6cdbMathias Agopian        // see if we timed out
3300408772e34931351d062f2088b611325ddaa6cdbMathias Agopian        if (isFrozen()) {
3310408772e34931351d062f2088b611325ddaa6cdbMathias Agopian            const nsecs_t now = systemTime();
3320408772e34931351d062f2088b611325ddaa6cdbMathias Agopian            nsecs_t frozenTime = (now - mFreezeDisplayTime);
3330408772e34931351d062f2088b611325ddaa6cdbMathias Agopian            if (frozenTime >= freezeDisplayTimeout) {
334edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                // we timed out and are still frozen
335edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                LOGW("timeout expired mFreezeDisplay=%d, mFreezeCount=%d",
336edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        mFreezeDisplay, mFreezeCount);
3370408772e34931351d062f2088b611325ddaa6cdbMathias Agopian                mFreezeDisplayTime = 0;
338edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mFreezeCount = 0;
339bcef13b666c7459241235bc6209837ae81884d2fThe Android Open Source Project                mFreezeDisplay = false;
3400408772e34931351d062f2088b611325ddaa6cdbMathias Agopian            }
3410408772e34931351d062f2088b611325ddaa6cdbMathias Agopian        }
3420408772e34931351d062f2088b611325ddaa6cdbMathias Agopian
3430408772e34931351d062f2088b611325ddaa6cdbMathias Agopian        if (msg != 0) {
3440408772e34931351d062f2088b611325ddaa6cdbMathias Agopian            switch (msg->what) {
3450408772e34931351d062f2088b611325ddaa6cdbMathias Agopian                case MessageQueue::INVALIDATE:
3460408772e34931351d062f2088b611325ddaa6cdbMathias Agopian                    // invalidate message, just return to the main loop
3470408772e34931351d062f2088b611325ddaa6cdbMathias Agopian                    return;
348edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
349edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
350edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
351edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
352edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
353edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::signalEvent() {
354f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    mEventQueue.invalidate();
355edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
356edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
357582270d69db94286a248bd829f1ae6f910d45124Jamie Gennisbool SurfaceFlinger::authenticateSurfaceTexture(
358582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis        const sp<ISurfaceTexture>& surfaceTexture) const {
359134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    Mutex::Autolock _l(mStateLock);
360582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis    sp<IBinder> surfaceTextureBinder(surfaceTexture->asBinder());
361134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
362134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // Check the visible layer list for the ISurface
363134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
364134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    size_t count = currentLayers.size();
365134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    for (size_t i=0 ; i<count ; i++) {
366134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        const sp<LayerBase>& layer(currentLayers[i]);
367134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        sp<LayerBaseClient> lbc(layer->getLayerBaseClient());
368582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis        if (lbc != NULL) {
369582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder();
370582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            if (lbcBinder == surfaceTextureBinder) {
371582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis                return true;
372582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            }
373134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        }
374134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    }
375134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
376134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // Check the layers in the purgatory.  This check is here so that if a
377582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis    // SurfaceTexture gets destroyed before all the clients are done using it,
378582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis    // the error will not be reported as "surface XYZ is not authenticated", but
379134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // will instead fail later on when the client tries to use the surface,
380134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // which should be reported as "surface XYZ returned an -ENODEV".  The
381134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // purgatorized layers are no less authentic than the visible ones, so this
382134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // should not cause any harm.
383134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    size_t purgatorySize =  mLayerPurgatory.size();
384134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    for (size_t i=0 ; i<purgatorySize ; i++) {
385134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
386134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        sp<LayerBaseClient> lbc(layer->getLayerBaseClient());
387582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis        if (lbc != NULL) {
388582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder();
389582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            if (lbcBinder == surfaceTextureBinder) {
390582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis                return true;
391582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            }
392134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        }
393134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    }
394134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
395134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    return false;
396134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis}
397134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
398bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg,
399bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        nsecs_t reltime, uint32_t flags)
400edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
401bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    return mEventQueue.postMessage(msg, reltime, flags);
402bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian}
403bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
404bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,
405bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        nsecs_t reltime, uint32_t flags)
406bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian{
407bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    status_t res = mEventQueue.postMessage(msg, reltime, flags);
408bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    if (res == NO_ERROR) {
409bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        msg->wait();
410bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    }
411bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    return res;
412edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
413edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
414edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
415edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if 0
416edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark -
417edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark Main loop
418edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif
419edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
420edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool SurfaceFlinger::threadLoop()
421edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
422edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    waitForEvent();
423edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
424edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // check for transactions
425edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(mConsoleSignals)) {
426edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        handleConsoleEvents();
427edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
428edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
429698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    // if we're in a global transaction, don't do anything.
430698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
431698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    uint32_t transactionFlags = peekTransactionFlags(mask);
432698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    if (UNLIKELY(transactionFlags)) {
433698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        handleTransaction(transactionFlags);
434edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
435edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
436edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // post surfaces (if needed)
437edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    handlePageFlip();
438edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
439a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    if (UNLIKELY(mHwWorkListDirty)) {
440a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        // build the h/w work list
441a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        handleWorkList();
442a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
443a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
444edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw(graphicPlane(0).displayHardware());
4458a77baaa11cb90f84d24f345463a856495be81a2Mathias Agopian    if (LIKELY(hw.canDraw() && !isFrozen())) {
446edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // repaint the framebuffer (if needed)
44735b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian
44835b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        const int index = hw.getCurrentBufferIndex();
44935b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        GraphicLog& logger(GraphicLog::getInstance());
45035b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian
45135b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        logger.log(GraphicLog::SF_REPAINT, index);
452edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        handleRepaint();
453edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
45474faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian        // inform the h/w that we're done compositing
45535b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        logger.log(GraphicLog::SF_COMPOSITION_COMPLETE, index);
45674faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian        hw.compositionComplete();
45774faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian
45835b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        logger.log(GraphicLog::SF_SWAP_BUFFERS, index);
4598392b504bdf63ac7820c79c7217a89f2b2411bd0Antti Hatala        postFramebuffer();
4608392b504bdf63ac7820c79c7217a89f2b2411bd0Antti Hatala
46135b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        logger.log(GraphicLog::SF_REPAINT_DONE, index);
462edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
463edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // pretend we did the post
464e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian        hw.compositionComplete();
465edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        usleep(16667); // 60 fps period
466edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
467edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return true;
468edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
469edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
470edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer()
471edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
472edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (!mInvalidRegion.isEmpty()) {
473edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const DisplayHardware& hw(graphicPlane(0).displayHardware());
4749795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const nsecs_t now = systemTime();
4759795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInSwapBuffers = now;
476edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        hw.flip(mInvalidRegion);
4779795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastSwapBufferTime = systemTime() - now;
4789795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInSwapBuffers = 0;
479edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mInvalidRegion.clear();
480edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
481edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
482edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
483edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleConsoleEvents()
484edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
485edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // something to do with the console
486edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw = graphicPlane(0).displayHardware();
487edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
488edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int what = android_atomic_and(0, &mConsoleSignals);
489edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (what & eConsoleAcquired) {
490edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        hw.acquireScreen();
4919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // this is a temporary work-around, eventually this should be called
4929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // by the power-manager
493abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        SurfaceFlinger::turnElectronBeamOn(mElectronBeamAnimationMode);
494edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
495edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
49659119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (mDeferReleaseConsole && hw.isScreenAcquired()) {
49762b74444be6742ab6b877918c85caeb9f2f1a2c9Mathias Agopian        // We got the release signal before the acquire signal
498edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDeferReleaseConsole = false;
499edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        hw.releaseScreen();
500edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
501edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
502edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (what & eConsoleReleased) {
50359119e658a12279e8fff508f8773843de2d90917Mathias Agopian        if (hw.isScreenAcquired()) {
504edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            hw.releaseScreen();
505edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
506edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mDeferReleaseConsole = true;
507edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
508edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
509edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
510edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDirtyRegion.set(hw.bounds());
511edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
512edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
513edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
514edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
515ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    Mutex::Autolock _l(mStateLock);
516ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    const nsecs_t now = systemTime();
517ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = now;
518ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
519ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // Here we're guaranteed that some transaction flags are set
520ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // so we can call handleTransactionLocked() unconditionally.
521ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // We call getTransactionFlags(), which will also clear the flags,
522ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // with mStateLock held to guarantee that mCurrentState won't change
523ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // until the transaction is committed.
524ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
525ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
526ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    transactionFlags = getTransactionFlags(mask);
527ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    handleTransactionLocked(transactionFlags);
528ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
529ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mLastTransactionTime = systemTime() - now;
530ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = 0;
531ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    invalidateHwcGeometry();
532ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // here the transaction has been committed
5333d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian}
534edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
535ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopianvoid SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
5363d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{
5373d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    const LayerVector& currentLayers(mCurrentState.layersSortedByZ);
538edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t count = currentLayers.size();
539edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
540edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
541edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Traversal of the children
542edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * (perform the transaction for each of them if needed)
543edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
544edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
545edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const bool layersNeedTransaction = transactionFlags & eTraversalNeeded;
546edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (layersNeedTransaction) {
547edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (size_t i=0 ; i<count ; i++) {
548076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            const sp<LayerBase>& layer = currentLayers[i];
549edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
550edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (!trFlags) continue;
551edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
552edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const uint32_t flags = layer->doTransaction(0);
553edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (flags & Layer::eVisibleRegion)
554edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mVisibleRegionsDirty = true;
555edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
556edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
557edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
558edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
559edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Perform our own transaction if needed
560edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
561edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (transactionFlags & eTransactionNeeded) {
563edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (mCurrentState.orientation != mDrawingState.orientation) {
564edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // the orientation has changed, recompute all visible regions
565edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // and invalidate everything.
566edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
567edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int dpy = 0;
568edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int orientation = mCurrentState.orientation;
569c08731e756868653d09d3e49b723706df3687070Mathias Agopian            const uint32_t type = mCurrentState.orientationType;
570edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            GraphicPlane& plane(graphicPlane(dpy));
571edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            plane.setOrientation(orientation);
572edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
573edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // update the shared control block
574edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const DisplayHardware& hw(plane.displayHardware());
575edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            volatile display_cblk_t* dcblk = mServerCblk->displays + dpy;
576edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dcblk->orientation = orientation;
5772b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            dcblk->w = plane.getWidth();
5782b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            dcblk->h = plane.getHeight();
579edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
580edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
581edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mDirtyRegion.set(hw.bounds());
582edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
583edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
584edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (mCurrentState.freezeDisplay != mDrawingState.freezeDisplay) {
585edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // freezing or unfreezing the display -> trigger animation if needed
586edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mFreezeDisplay = mCurrentState.freezeDisplay;
587064e1e672e62094b32f8cf7a77a3b04c3309dc79Mathias Agopian            if (mFreezeDisplay)
588064e1e672e62094b32f8cf7a77a3b04c3309dc79Mathias Agopian                 mFreezeDisplayTime = 0;
589edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
590edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5910aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        if (currentLayers.size() > mDrawingState.layersSortedByZ.size()) {
5920aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            // layers have been added
593edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
594edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
595edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5960aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        // some layers might have been removed, so
5970aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        // we need to update the regions they're exposing.
5980aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        if (mLayersRemoved) {
59948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian            mLayersRemoved = false;
600edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
6010aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            const LayerVector& previousLayers(mDrawingState.layersSortedByZ);
6023d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian            const size_t count = previousLayers.size();
6033d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian            for (size_t i=0 ; i<count ; i++) {
6040aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                const sp<LayerBase>& layer(previousLayers[i]);
6050aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                if (currentLayers.indexOf( layer ) < 0) {
6060aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                    // this layer is not visible anymore
6075d7126b625c8c4a7b945e8c247b63abff7bc13b6Mathias Agopian                    mDirtyRegionRemovedLayer.orSelf(layer->visibleRegionScreen);
6080aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                }
6090aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            }
610edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
611edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
612edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
613edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    commitTransaction();
614edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
615edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
616edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectsp<FreezeLock> SurfaceFlinger::getFreezeLock() const
617edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
618edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return new FreezeLock(const_cast<SurfaceFlinger *>(this));
619edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
620edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
621edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::computeVisibleRegions(
6221bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian    const LayerVector& currentLayers, Region& dirtyRegion, Region& opaqueRegion)
623edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
624edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(graphicPlane(0));
625edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Transform& planeTransform(plane.transform());
626ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian    const DisplayHardware& hw(plane.displayHardware());
627ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian    const Region screenRegion(hw.bounds());
628edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
629edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveOpaqueLayers;
630edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveCoveredLayers;
631edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region dirty;
632edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
633edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    bool secureFrameBuffer = false;
634edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
635edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t i = currentLayers.size();
636edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    while (i--) {
637076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        const sp<LayerBase>& layer = currentLayers[i];
638edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->validateVisibility(planeTransform);
639edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
640edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // start with the whole surface at its current location
641970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian        const Layer::State& s(layer->drawingState());
642edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
643ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
644ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * opaqueRegion: area of a surface that is fully opaque.
645ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
646edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region opaqueRegion;
647ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
648ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
649ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visibleRegion: area of a surface that is visible on screen
650ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * and not fully transparent. This is essentially the layer's
651ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * footprint minus the opaque regions above it.
652ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * Areas covered by a translucent surface are considered visible.
653ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
654edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region visibleRegion;
655ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
656ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
657ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * coveredRegion: area of a surface that is covered by all
658ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visible regions above it (which includes the translucent areas).
659ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
660edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region coveredRegion;
661ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
662ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
663ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // handle hidden surfaces by setting the visible region to empty
664970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian        if (LIKELY(!(s.flags & ISurfaceComposer::eLayerHidden) && s.alpha)) {
665a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            const bool translucent = !layer->isOpaque();
666970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian            const Rect bounds(layer->visibleBounds());
667edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            visibleRegion.set(bounds);
668ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            visibleRegion.andSelf(screenRegion);
669ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            if (!visibleRegion.isEmpty()) {
670ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // Remove the transparent area from the visible region
671ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (translucent) {
672ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    visibleRegion.subtractSelf(layer->transparentRegionScreen);
673ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
674edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
675ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // compute the opaque region
676ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                const int32_t layerOrientation = layer->getOrientation();
677ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (s.alpha==255 && !translucent &&
678ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                        ((layerOrientation & Transform::ROT_INVALID) == false)) {
679ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    // the opaque region is the layer's footprint
680ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    opaqueRegion = visibleRegion;
681ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
682edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
683edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
684edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
685ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Clip the covered region to the visible region
686ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        coveredRegion = aboveCoveredLayers.intersect(visibleRegion);
687ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
688ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveCoveredLayers for next (lower) layer
689ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        aboveCoveredLayers.orSelf(visibleRegion);
690ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
691edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // subtract the opaque region covered by the layers above us
692edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        visibleRegion.subtractSelf(aboveOpaqueLayers);
693edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
694edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // compute this layer's dirty region
695edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (layer->contentDirty) {
696edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // we need to invalidate the whole region
697edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dirty = visibleRegion;
698edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // as well, as the old visible region
699edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dirty.orSelf(layer->visibleRegionScreen);
700edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->contentDirty = false;
701edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
702a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian            /* compute the exposed region:
703ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   the exposed region consists of two components:
704ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   1) what's VISIBLE now and was COVERED before
705ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   2) what's EXPOSED now less what was EXPOSED before
706ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
707ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * note that (1) is conservative, we start with the whole
708ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * visible region but only keep what used to be covered by
709ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * something -- which mean it may have been exposed.
710ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
711ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * (2) handles areas that were not covered by anything but got
712ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * exposed because of a resize.
713a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian             */
714ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region newExposed = visibleRegion - coveredRegion;
715ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldVisibleRegion = layer->visibleRegionScreen;
716ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldCoveredRegion = layer->coveredRegionScreen;
717ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldExposed = oldVisibleRegion - oldCoveredRegion;
718ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed);
719edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
720edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirty.subtractSelf(aboveOpaqueLayers);
721edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
722edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // accumulate to the screen dirty region
723edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirtyRegion.orSelf(dirty);
724edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
725ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveOpaqueLayers for next (lower) layer
726edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        aboveOpaqueLayers.orSelf(opaqueRegion);
7278b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
728edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // Store the visible region is screen space
729edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setVisibleRegion(visibleRegion);
730edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setCoveredRegion(coveredRegion);
731edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
732970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian        // If a secure layer is partially visible, lock-down the screen!
733edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (layer->isSecure() && !visibleRegion.isEmpty()) {
734edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            secureFrameBuffer = true;
735edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
736edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
737edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
738970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian    // invalidate the areas where a layer was removed
739970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian    dirtyRegion.orSelf(mDirtyRegionRemovedLayer);
740970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian    mDirtyRegionRemovedLayer.clear();
741970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian
742edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mSecureFrameBuffer = secureFrameBuffer;
743edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    opaqueRegion = aboveOpaqueLayers;
744edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
745edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
746edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
747edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::commitTransaction()
748edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
749edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDrawingState = mCurrentState;
750cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mResizeTransationPending = false;
751cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mTransactionCV.broadcast();
752edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
753edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
754edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handlePageFlip()
755edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
756edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    bool visibleRegions = mVisibleRegionsDirty;
7571bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian    const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
758edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    visibleRegions |= lockPageFlip(currentLayers);
759edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
760edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const DisplayHardware& hw = graphicPlane(0).displayHardware();
761edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const Region screenRegion(hw.bounds());
762edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (visibleRegions) {
763edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            Region opaqueRegion;
764edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            computeVisibleRegions(currentLayers, mDirtyRegion, opaqueRegion);
7654da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
7664da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            /*
7674da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian             *  rebuild the visible layer list
7684da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian             */
7691bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian            const size_t count = currentLayers.size();
7704da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            mVisibleLayersSortedByZ.clear();
7714da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            mVisibleLayersSortedByZ.setCapacity(count);
7724da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            for (size_t i=0 ; i<count ; i++) {
7734da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian                if (!currentLayers[i]->visibleRegionScreen.isEmpty())
7744da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian                    mVisibleLayersSortedByZ.add(currentLayers[i]);
7754da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            }
7764da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
777edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mWormholeRegion = screenRegion.subtract(opaqueRegion);
778edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = false;
779ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian            invalidateHwcGeometry();
780edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
781edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
782edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    unlockPageFlip(currentLayers);
783edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDirtyRegion.andSelf(screenRegion);
784edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
785edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
786ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopianvoid SurfaceFlinger::invalidateHwcGeometry()
787ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian{
788ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian    mHwWorkListDirty = true;
789ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian}
790ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian
791edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool SurfaceFlinger::lockPageFlip(const LayerVector& currentLayers)
792edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
793edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    bool recomputeVisibleRegions = false;
794edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t count = currentLayers.size();
795076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBase> const* layers = currentLayers.array();
796edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (size_t i=0 ; i<count ; i++) {
797b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
798edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->lockPageFlip(recomputeVisibleRegions);
799edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
800edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return recomputeVisibleRegions;
801edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
802edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
803edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::unlockPageFlip(const LayerVector& currentLayers)
804edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
805edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(graphicPlane(0));
806edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Transform& planeTransform(plane.transform());
807edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t count = currentLayers.size();
808076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBase> const* layers = currentLayers.array();
809edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (size_t i=0 ; i<count ; i++) {
810b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
811edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->unlockPageFlip(planeTransform, mDirtyRegion);
812edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
813edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
814edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
815a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopianvoid SurfaceFlinger::handleWorkList()
816a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian{
817a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    mHwWorkListDirty = false;
818a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    HWComposer& hwc(graphicPlane(0).displayHardware().getHwComposer());
819a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    if (hwc.initCheck() == NO_ERROR) {
820a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        const Vector< sp<LayerBase> >& currentLayers(mVisibleLayersSortedByZ);
821a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        const size_t count = currentLayers.size();
822a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        hwc.createWorkList(count);
82345721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        hwc_layer_t* const cur(hwc.getLayers());
82445721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        for (size_t i=0 ; cur && i<count ; i++) {
82545721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            currentLayers[i]->setGeometry(&cur[i]);
82653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian            if (mDebugDisableHWC || mDebugRegion) {
82773d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian                cur[i].compositionType = HWC_FRAMEBUFFER;
82873d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian                cur[i].flags |= HWC_SKIP_LAYER;
82973d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian            }
830a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        }
831a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
832a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian}
833b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian
834edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleRepaint()
835edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
836b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // compute the invalid region
837b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    mInvalidRegion.orSelf(mDirtyRegion);
838edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
839edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(mDebugRegion)) {
840edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        debugFlashRegions();
841edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
842edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
843b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // set the frame buffer
844b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
845b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    glMatrixMode(GL_MODELVIEW);
846b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    glLoadIdentity();
847edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
848edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t flags = hw.getFlags();
8498b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber    if ((flags & DisplayHardware::SWAP_RECTANGLE) ||
8508b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber        (flags & DisplayHardware::BUFFER_PRESERVED))
851df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian    {
85229d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // we can redraw only what's dirty, but since SWAP_RECTANGLE only
85329d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // takes a rectangle, we must make sure to update that whole
85429d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // rectangle in that case
85529d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        if (flags & DisplayHardware::SWAP_RECTANGLE) {
856b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            // TODO: we really should be able to pass a region to
85729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // SWAP_RECTANGLE so that we don't have to redraw all this.
85829d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            mDirtyRegion.set(mInvalidRegion.bounds());
85929d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        } else {
86029d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // in the BUFFER_PRESERVED case, obviously, we can update only
86129d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // what's needed and nothing more.
86229d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // NOTE: this is NOT a common case, as preserving the backbuffer
86329d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // is costly and usually involves copying the whole update back.
86429d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        }
865edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
86695a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian        if (flags & DisplayHardware::PARTIAL_UPDATES) {
86729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // We need to redraw the rectangle that will be updated
868df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian            // (pushed to the framebuffer).
86995a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian            // This is needed because PARTIAL_UPDATES only takes one
87029d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // rectangle instead of a region (see DisplayHardware::flip())
871edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mDirtyRegion.set(mInvalidRegion.bounds());
872edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
87329d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // we need to redraw everything (the whole screen)
874edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mDirtyRegion.set(hw.bounds());
875edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mInvalidRegion = mDirtyRegion;
876edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
877edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
878edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
879edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // compose all surfaces
880edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    composeSurfaces(mDirtyRegion);
881edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
882edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // clear the dirty regions
883edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDirtyRegion.clear();
884edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
885edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
886edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::composeSurfaces(const Region& dirty)
887edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
888edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(!mWormholeRegion.isEmpty())) {
889edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // should never happen unless the window manager has a bug
890edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // draw something...
891edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        drawWormhole();
892edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
893a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
894a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    status_t err = NO_ERROR;
8954da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian    const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
89645721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    size_t count = layers.size();
897a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
898a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
899a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    HWComposer& hwc(hw.getHwComposer());
90045721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    hwc_layer_t* const cur(hwc.getLayers());
901a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
90245721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    LOGE_IF(cur && hwc.getNumLayers() != count,
90345721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            "HAL number of layers (%d) doesn't match surfaceflinger (%d)",
90445721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            hwc.getNumLayers(), count);
905a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
90645721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    // just to be extra-safe, use the smallest count
90724925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling    if (hwc.initCheck() == NO_ERROR) {
90824925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling        count = count < hwc.getNumLayers() ? count : hwc.getNumLayers();
90924925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling    }
910a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
91145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    /*
91245721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     *  update the per-frame h/w composer data for each layer
91345721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     *  and build the transparent region of the FB
91445721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     */
91545721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    Region transparent;
91645721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    if (cur) {
91745721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        for (size_t i=0 ; i<count ; i++) {
91845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            const sp<LayerBase>& layer(layers[i]);
91945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            layer->setPerFrameData(&cur[i]);
920edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
92145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        err = hwc.prepare();
92245721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        LOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
923a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
924f20a32415d055336bc6016fa2de36d126db32746Mathias Agopian        if (err == NO_ERROR) {
925f20a32415d055336bc6016fa2de36d126db32746Mathias Agopian            for (size_t i=0 ; i<count ; i++) {
926f20a32415d055336bc6016fa2de36d126db32746Mathias Agopian                if (cur[i].hints & HWC_HINT_CLEAR_FB) {
927f20a32415d055336bc6016fa2de36d126db32746Mathias Agopian                    const sp<LayerBase>& layer(layers[i]);
928a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                    if (layer->isOpaque()) {
929f20a32415d055336bc6016fa2de36d126db32746Mathias Agopian                        transparent.orSelf(layer->visibleRegionScreen);
930f20a32415d055336bc6016fa2de36d126db32746Mathias Agopian                    }
931f20a32415d055336bc6016fa2de36d126db32746Mathias Agopian                }
932f20a32415d055336bc6016fa2de36d126db32746Mathias Agopian            }
933f20a32415d055336bc6016fa2de36d126db32746Mathias Agopian
934f20a32415d055336bc6016fa2de36d126db32746Mathias Agopian            /*
935f20a32415d055336bc6016fa2de36d126db32746Mathias Agopian             *  clear the area of the FB that need to be transparent
936f20a32415d055336bc6016fa2de36d126db32746Mathias Agopian             */
937f20a32415d055336bc6016fa2de36d126db32746Mathias Agopian            transparent.andSelf(dirty);
938f20a32415d055336bc6016fa2de36d126db32746Mathias Agopian            if (!transparent.isEmpty()) {
939f20a32415d055336bc6016fa2de36d126db32746Mathias Agopian                glClearColor(0,0,0,0);
940f20a32415d055336bc6016fa2de36d126db32746Mathias Agopian                Region::const_iterator it = transparent.begin();
941f20a32415d055336bc6016fa2de36d126db32746Mathias Agopian                Region::const_iterator const end = transparent.end();
942f20a32415d055336bc6016fa2de36d126db32746Mathias Agopian                const int32_t height = hw.getHeight();
943f20a32415d055336bc6016fa2de36d126db32746Mathias Agopian                while (it != end) {
944f20a32415d055336bc6016fa2de36d126db32746Mathias Agopian                    const Rect& r(*it++);
945f20a32415d055336bc6016fa2de36d126db32746Mathias Agopian                    const GLint sy = height - (r.top + r.height());
946f20a32415d055336bc6016fa2de36d126db32746Mathias Agopian                    glScissor(r.left, sy, r.width(), r.height());
947f20a32415d055336bc6016fa2de36d126db32746Mathias Agopian                    glClear(GL_COLOR_BUFFER_BIT);
948f20a32415d055336bc6016fa2de36d126db32746Mathias Agopian                }
949f20a32415d055336bc6016fa2de36d126db32746Mathias Agopian            }
950a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        }
951a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
95245721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian
95345721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian
95445721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    /*
95545721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     * and then, render the layers targeted at the framebuffer
95645721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     */
95745721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
95845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        if (cur) {
959586a0deb76012c4347298c11df460631853b67f8Antti Hatala            if ((cur[i].compositionType != HWC_FRAMEBUFFER) &&
960586a0deb76012c4347298c11df460631853b67f8Antti Hatala                !(cur[i].flags & HWC_SKIP_LAYER)) {
96145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian                // skip layers handled by the HAL
96245721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian                continue;
96345721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            }
96445721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        }
96573d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian
96645721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
96745721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        const Region clip(dirty.intersect(layer->visibleRegionScreen));
96845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        if (!clip.isEmpty()) {
96945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            layer->draw(clip);
97045721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        }
97145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    }
972edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
973edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
974edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::debugFlashRegions()
975edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
9760a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
9770a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    const uint32_t flags = hw.getFlags();
97853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian    const int32_t height = hw.getHeight();
97953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian    if (mInvalidRegion.isEmpty()) {
98053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian        return;
98153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian    }
9820a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
9830a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    if (!((flags & DisplayHardware::SWAP_RECTANGLE) ||
9840a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian            (flags & DisplayHardware::BUFFER_PRESERVED))) {
9850a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        const Region repaint((flags & DisplayHardware::PARTIAL_UPDATES) ?
9860a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian                mDirtyRegion.bounds() : hw.bounds());
9870a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        composeSurfaces(repaint);
9880a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    }
9890a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
990edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_BLEND);
991edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_DITHER);
992edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_SCISSOR_TEST);
993edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
9940926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    static int toggle = 0;
9950926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    toggle = 1 - toggle;
9960926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    if (toggle) {
9970a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        glColor4f(1, 0, 1, 1);
9980926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    } else {
9990a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        glColor4f(1, 1, 0, 1);
10000926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    }
1001edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
100220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    Region::const_iterator it = mDirtyRegion.begin();
100320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    Region::const_iterator const end = mDirtyRegion.end();
100420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    while (it != end) {
100520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        const Rect& r = *it++;
1006edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLfloat vertices[][2] = {
100753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.left,  height - r.top },
100853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.left,  height - r.bottom },
100953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.right, height - r.bottom },
101053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.right, height - r.top }
1011edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        };
1012edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glVertexPointer(2, GL_FLOAT, 0, vertices);
1013edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1014edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
10150a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
1016b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    hw.flip(mInvalidRegion);
1017edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1018edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mDebugRegion > 1)
10190a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        usleep(mDebugRegion * 1000);
1020edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1021edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glEnable(GL_SCISSOR_TEST);
1022edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1023edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1024edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::drawWormhole() const
1025edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1026edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Region region(mWormholeRegion.intersect(mDirtyRegion));
1027edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (region.isEmpty())
1028edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1029edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1030edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw(graphicPlane(0).displayHardware());
1031edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int32_t width = hw.getWidth();
1032edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int32_t height = hw.getHeight();
1033edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1034edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_BLEND);
1035edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_DITHER);
1036edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1037edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (LIKELY(!mDebugBackground)) {
10380a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        glClearColor(0,0,0,0);
103920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        Region::const_iterator it = region.begin();
104020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        Region::const_iterator const end = region.end();
104120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        while (it != end) {
104220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            const Rect& r = *it++;
1043edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const GLint sy = height - (r.top + r.height());
1044edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glScissor(r.left, sy, r.width(), r.height());
1045edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glClear(GL_COLOR_BUFFER_BIT);
1046edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1047edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
1048edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GLshort vertices[][2] = { { 0, 0 }, { width, 0 },
1049edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                { width, height }, { 0, height }  };
1050edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GLshort tcoords[][2] = { { 0, 0 }, { 1, 0 },  { 1, 1 }, { 0, 1 } };
1051edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glVertexPointer(2, GL_SHORT, 0, vertices);
1052edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glTexCoordPointer(2, GL_SHORT, 0, tcoords);
1053edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
10547f198b6bff54af3c8e8ac32b83ffc6488e773ac1Michael I. Gold#if defined(GL_OES_EGL_image_external)
10551f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian        if (GLExtensions::getInstance().haveTextureExternal()) {
10561f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian            glDisable(GL_TEXTURE_EXTERNAL_OES);
10571f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian        }
10580a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian#endif
1059edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glEnable(GL_TEXTURE_2D);
1060edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glBindTexture(GL_TEXTURE_2D, mWormholeTexName);
1061edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1062edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glMatrixMode(GL_TEXTURE);
1063edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glLoadIdentity();
1064edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glScalef(width*(1.0f/32.0f), height*(1.0f/32.0f), 1);
106520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        Region::const_iterator it = region.begin();
106620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        Region::const_iterator const end = region.end();
106720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        while (it != end) {
106820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            const Rect& r = *it++;
1069edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const GLint sy = height - (r.top + r.height());
1070edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glScissor(r.left, sy, r.width(), r.height());
1071edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1072edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1073edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1074a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        glDisable(GL_TEXTURE_2D);
1075ebeb7095961e09f5cff0c7cf2c04fa4770b2e033Mathias Agopian        glLoadIdentity();
1076ebeb7095961e09f5cff0c7cf2c04fa4770b2e033Mathias Agopian        glMatrixMode(GL_MODELVIEW);
1077edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1078edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1079edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1080edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::debugShowFPS() const
1081edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1082edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    static int mFrameCount;
1083edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    static int mLastFrameCount = 0;
1084edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    static nsecs_t mLastFpsTime = 0;
1085edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    static float mFps = 0;
1086edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mFrameCount++;
1087edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    nsecs_t now = systemTime();
1088edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    nsecs_t diff = now - mLastFpsTime;
1089edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (diff > ms2ns(250)) {
1090edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mFps =  ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff;
1091edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mLastFpsTime = now;
1092edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mLastFrameCount = mFrameCount;
1093edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1094edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // XXX: mFPS has the value we want
1095edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project }
1096edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1097076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::addLayer(const sp<LayerBase>& layer)
1098edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1099edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
1100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    addLayer_l(layer);
1101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
1102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1105076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::addLayer_l(const sp<LayerBase>& layer)
1106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1107f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian    ssize_t i = mCurrentState.layersSortedByZ.add(layer);
11081b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    return (i < 0) ? status_t(i) : status_t(NO_ERROR);
11091b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian}
11101b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
111196f0819f81293076e652792794a961543e6750d7Mathias Agopianssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
111296f0819f81293076e652792794a961543e6750d7Mathias Agopian        const sp<LayerBaseClient>& lbc)
11131b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
111496f0819f81293076e652792794a961543e6750d7Mathias Agopian    // attach this layer to the client
11154f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    size_t name = client->attachLayer(lbc);
11164f113740180b6512b43723c4728f262882dc9b45Mathias Agopian
11174f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    Mutex::Autolock _l(mStateLock);
111896f0819f81293076e652792794a961543e6750d7Mathias Agopian
111996f0819f81293076e652792794a961543e6750d7Mathias Agopian    // add this layer to the current state list
112096f0819f81293076e652792794a961543e6750d7Mathias Agopian    addLayer_l(lbc);
112196f0819f81293076e652792794a961543e6750d7Mathias Agopian
11224f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    return ssize_t(name);
112396f0819f81293076e652792794a961543e6750d7Mathias Agopian}
112496f0819f81293076e652792794a961543e6750d7Mathias Agopian
112596f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer)
112696f0819f81293076e652792794a961543e6750d7Mathias Agopian{
112796f0819f81293076e652792794a961543e6750d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
112896f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = purgatorizeLayer_l(layer);
112996f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR)
113096f0819f81293076e652792794a961543e6750d7Mathias Agopian        setTransactionFlags(eTransactionNeeded);
113196f0819f81293076e652792794a961543e6750d7Mathias Agopian    return err;
1132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1134076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase)
1135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1136b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<LayerBaseClient> lbc(layerBase->getLayerBaseClient());
1137b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (lbc != 0) {
11380d1561275e80073807ac04728951782d943f8882Mathias Agopian        mLayerMap.removeItem( lbc->getSurfaceBinder() );
1139b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    }
1140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase);
1141edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (index >= 0) {
1142076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved = true;
1143edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
1144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
11453d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    return status_t(index);
1146edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1147edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
11489a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase)
11499a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
115076cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    // First add the layer to the purgatory list, which makes sure it won't
115176cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    // go away, then remove it from the main list (through a transaction).
11529a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    ssize_t err = removeLayer_l(layerBase);
115376cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    if (err >= 0) {
115476cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian        mLayerPurgatory.add(layerBase);
115576cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    }
11568c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian
11570b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian    layerBase->onRemoved();
11580b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian
11593d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // it's possible that we don't find a layer, because it might
11603d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // have been destroyed already -- this is not technically an error
116196f0819f81293076e652792794a961543e6750d7Mathias Agopian    // from the user because there is a race between Client::destroySurface(),
116296f0819f81293076e652792794a961543e6750d7Mathias Agopian    // ~Client() and ~ISurface().
11639a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err;
11649a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
11659a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
116696f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::invalidateLayerVisibility(const sp<LayerBase>& layer)
1167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
116896f0819f81293076e652792794a961543e6750d7Mathias Agopian    layer->forceVisibilityTransaction();
116996f0819f81293076e652792794a961543e6750d7Mathias Agopian    setTransactionFlags(eTraversalNeeded);
117096f0819f81293076e652792794a961543e6750d7Mathias Agopian    return NO_ERROR;
1171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1173dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopianuint32_t SurfaceFlinger::peekTransactionFlags(uint32_t flags)
1174dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian{
1175dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian    return android_atomic_release_load(&mTransactionFlags);
1176dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian}
1177dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian
1178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags)
1179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return android_atomic_and(~flags, &mTransactionFlags) & flags;
1181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1183bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags)
1184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t old = android_atomic_or(flags, &mTransactionFlags);
1186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((old & flags)==0) { // wake the server up
1187bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        signalEvent();
1188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return old;
1190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1193698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopianvoid SurfaceFlinger::setTransactionState(const Vector<ComposerState>& state) {
1194698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
1195cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
1196698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    uint32_t flags = 0;
1197698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    const size_t count = state.size();
1198698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
1199698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const ComposerState& s(state[i]);
1200698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        sp<Client> client( static_cast<Client *>(s.client.get()) );
1201698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        flags |= setClientStateLocked(client, s.state);
1202698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    }
1203698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    if (flags) {
1204698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        setTransactionFlags(flags);
1205698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    }
1206698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian
1207698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    signalEvent();
1208698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian
1209698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    // if there is a transaction with a resize, wait for it to
1210698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    // take effect before returning.
1211698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    while (mResizeTransationPending) {
1212698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
1213698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (CC_UNLIKELY(err != NO_ERROR)) {
1214698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            // just in case something goes wrong in SF, return to the
1215698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            // called after a few seconds.
1216698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            LOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!");
1217698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            mResizeTransationPending = false;
1218698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            break;
1219cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        }
1220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::freezeDisplay(DisplayID dpy, uint32_t flags)
1224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
1226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return BAD_VALUE;
1227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
1229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mCurrentState.freezeDisplay = 1;
1230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    setTransactionFlags(eTransactionNeeded);
1231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // flags is intended to communicate some sort of animation behavior
123362b74444be6742ab6b877918c85caeb9f2f1a2c9Mathias Agopian    // (for instance fading)
1234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::unfreezeDisplay(DisplayID dpy, uint32_t flags)
1238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
1240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return BAD_VALUE;
1241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
1243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mCurrentState.freezeDisplay = 0;
1244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    setTransactionFlags(eTransactionNeeded);
1245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // flags is intended to communicate some sort of animation behavior
124762b74444be6742ab6b877918c85caeb9f2f1a2c9Mathias Agopian    // (for instance fading)
1248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
12518b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huberint SurfaceFlinger::setOrientation(DisplayID dpy,
1252c08731e756868653d09d3e49b723706df3687070Mathias Agopian        int orientation, uint32_t flags)
1253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
1255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return BAD_VALUE;
1256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
1258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mCurrentState.orientation != orientation) {
1259edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (uint32_t(orientation)<=eOrientation270 || orientation==42) {
1260c08731e756868653d09d3e49b723706df3687070Mathias Agopian            mCurrentState.orientationType = flags;
1261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mCurrentState.orientation = orientation;
1262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            setTransactionFlags(eTransactionNeeded);
1263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mTransactionCV.wait(mStateLock);
1264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
1265edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            orientation = BAD_VALUE;
1266edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1267edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return orientation;
1269edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
12710ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopiansp<ISurface> SurfaceFlinger::createSurface(
12720ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        ISurfaceComposerClient::surface_data_t* params,
12730ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const String8& name,
12740ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const sp<Client>& client,
1275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        DisplayID d, uint32_t w, uint32_t h, PixelFormat format,
1276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t flags)
1277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1278076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBaseClient> layer;
1279a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    sp<ISurface> surfaceHandle;
12806e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian
12816e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    if (int32_t(w|h) < 0) {
12826e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian        LOGE("createSurface() failed, w or h is negative (w=%d, h=%d)",
12836e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian                int(w), int(h));
12846e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian        return surfaceHandle;
12856e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    }
12868b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
1287edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    //LOGD("createSurface for pid %d (%d x %d)", pid, w, h);
1288b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<Layer> normalLayer;
1289edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (flags & eFXSurfaceMask) {
1290edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceNormal:
1291a5529c8778c2f407f482fc12165aeb76c0f505c2Mathias Agopian            normalLayer = createNormalSurface(client, d, w, h, flags, format);
1292a5529c8778c2f407f482fc12165aeb76c0f505c2Mathias Agopian            layer = normalLayer;
1293edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
1294edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceBlur:
12951293a8eb567fd63c072a6970fa9dcf37d076059fMathias Agopian            // for now we treat Blur as Dim, until we can implement it
12961293a8eb567fd63c072a6970fa9dcf37d076059fMathias Agopian            // efficiently.
1297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceDim:
129896f0819f81293076e652792794a961543e6750d7Mathias Agopian            layer = createDimSurface(client, d, w, h, flags);
1299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
1300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1301edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1302076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (layer != 0) {
130396f0819f81293076e652792794a961543e6750d7Mathias Agopian        layer->initStates(w, h, flags);
1304285dbde2e0cd0057be070ded3be8f5f453147edcMathias Agopian        layer->setName(name);
130596f0819f81293076e652792794a961543e6750d7Mathias Agopian        ssize_t token = addClientLayer(client, layer);
1306b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        surfaceHandle = layer->getSurface();
13088b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber        if (surfaceHandle != 0) {
130996f0819f81293076e652792794a961543e6750d7Mathias Agopian            params->token = token;
1310a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            params->identity = layer->getIdentity();
1311b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            if (normalLayer != 0) {
1312b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian                Mutex::Autolock _l(mStateLock);
1313a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                mLayerMap.add(layer->getSurfaceBinder(), normalLayer);
1314b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            }
13151c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        }
1316b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
131796f0819f81293076e652792794a961543e6750d7Mathias Agopian        setTransactionFlags(eTransactionNeeded);
1318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return surfaceHandle;
1321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1323b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<Layer> SurfaceFlinger::createNormalSurface(
1324f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        const sp<Client>& client, DisplayID display,
132596f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags,
13261c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        PixelFormat& format)
1327edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1328edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize the surfaces
1329edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (format) { // TODO: take h/w into account
1330edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSPARENT:
1331edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSLUCENT:
1332edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        format = PIXEL_FORMAT_RGBA_8888;
1333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1334edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_OPAQUE:
1335a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888
1336a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian        format = PIXEL_FORMAT_RGB_565;
1337a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#else
13388f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian        format = PIXEL_FORMAT_RGBX_8888;
1339a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif
1340edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1341edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1342edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1343a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888
1344a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian    if (format == PIXEL_FORMAT_RGBX_8888)
1345a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian        format = PIXEL_FORMAT_RGBA_8888;
1346a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif
1347a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian
134896f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<Layer> layer = new Layer(this, display, client);
1349f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian    status_t err = layer->setBuffers(w, h, format, flags);
135096f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (LIKELY(err != NO_ERROR)) {
1351edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        LOGE("createNormalSurfaceLocked() failed (%s)", strerror(-err));
1352076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        layer.clear();
1353edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1354edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1355edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1356edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1357b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<LayerDim> SurfaceFlinger::createDimSurface(
1358f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        const sp<Client>& client, DisplayID display,
135996f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags)
1360edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
136196f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<LayerDim> layer = new LayerDim(this, display, client);
1362edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    layer->initStates(w, h, flags);
1363edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1364edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1365edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
136696f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeSurface(const sp<Client>& client, SurfaceID sid)
13679a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
13689a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    /*
13699a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     * called by the window manager, when a surface should be marked for
13709a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     * destruction.
13718b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber     *
13720aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * The surface is removed from the current and drawing lists, but placed
13730aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * in the purgatory queue, so it's not destroyed right-away (we need
13740aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * to wait for all client's references to go away first).
13759a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     */
13769a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
137748d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    status_t err = NAME_NOT_FOUND;
13780aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian    Mutex::Autolock _l(mStateLock);
137996f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<LayerBaseClient> layer = client->getLayerUser(sid);
138048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    if (layer != 0) {
138148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        err = purgatorizeLayer_l(layer);
138248d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        if (err == NO_ERROR) {
138348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian            setTransactionFlags(eTransactionNeeded);
138448d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        }
13859a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    }
13869a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return err;
13879a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
13889a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
1389ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopianstatus_t SurfaceFlinger::destroySurface(const wp<LayerBaseClient>& layer)
1390edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1391759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian    // called by ~ISurface() when all references are gone
1392ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    status_t err = NO_ERROR;
1393ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    sp<LayerBaseClient> l(layer.promote());
1394ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    if (l != NULL) {
1395ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        Mutex::Autolock _l(mStateLock);
1396ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        err = removeLayer_l(l);
1397ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        if (err == NAME_NOT_FOUND) {
1398ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // The surface wasn't in the current list, which means it was
1399ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // removed already, which means it is in the purgatory,
1400ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // and need to be removed from there.
1401ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            ssize_t idx = mLayerPurgatory.remove(l);
1402ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            LOGE_IF(idx < 0,
1403ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian                    "layer=%p is not in the purgatory list", l.get());
1404f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        }
1405ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        LOGE_IF(err<0 && err != NAME_NOT_FOUND,
1406ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian                "error removing layer=%p (%s)", l.get(), strerror(-err));
1407ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    }
1408ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    return err;
1409edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1410edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1411698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopianuint32_t SurfaceFlinger::setClientStateLocked(
141296f0819f81293076e652792794a961543e6750d7Mathias Agopian        const sp<Client>& client,
1413698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const layer_state_t& s)
1414edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1415edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t flags = 0;
1416698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    sp<LayerBaseClient> layer(client->getLayerUser(s.surface));
1417698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    if (layer != 0) {
1418698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const uint32_t what = s.what;
1419698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & ePositionChanged) {
1420698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setPosition(s.x, s.y))
1421698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1422698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1423698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eLayerChanged) {
1424698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
1425698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setLayer(s.z)) {
1426698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                mCurrentState.layersSortedByZ.removeAt(idx);
1427698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                mCurrentState.layersSortedByZ.add(layer);
1428698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                // we need traversal (state changed)
1429698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                // AND transaction (list changed)
1430698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTransactionNeeded|eTraversalNeeded;
1431edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1432698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1433698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eSizeChanged) {
1434698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setSize(s.w, s.h)) {
1435698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1436698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                mResizeTransationPending = true;
1437edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1438edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1439698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eAlphaChanged) {
1440698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f)))
1441698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1442698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1443698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eMatrixChanged) {
1444698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setMatrix(s.matrix))
1445698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1446698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1447698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eTransparentRegionChanged) {
1448698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setTransparentRegionHint(s.transparentRegion))
1449698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1450698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1451698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eVisibilityChanged) {
1452698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setFlags(s.flags, s.mask))
1453698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1454698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1455edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1456698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    return flags;
1457edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1458edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1459edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::screenReleased(int dpy)
1460edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1461edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // this may be called by a signal handler, we can't do too much in here
1462edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    android_atomic_or(eConsoleReleased, &mConsoleSignals);
1463edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    signalEvent();
1464edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1465edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1466edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::screenAcquired(int dpy)
1467edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1468edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // this may be called by a signal handler, we can't do too much in here
1469edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    android_atomic_or(eConsoleAcquired, &mConsoleSignals);
1470edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    signalEvent();
1471edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1472edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1473edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
1474edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
14751d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling    const size_t SIZE = 4096;
1476edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char buffer[SIZE];
1477edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    String8 result;
147899b49840d309727678b77403d6cc9f920111623fMathias Agopian
147999b49840d309727678b77403d6cc9f920111623fMathias Agopian    if (!PermissionCache::checkCallingPermission(sDump)) {
1480edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        snprintf(buffer, SIZE, "Permission Denial: "
1481edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                "can't dump SurfaceFlinger from pid=%d, uid=%d\n",
1482edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                IPCThreadState::self()->getCallingPid(),
1483edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                IPCThreadState::self()->getCallingUid());
1484edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        result.append(buffer);
1485edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
14869795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
14879795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // figure out if we're stuck somewhere
14889795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const nsecs_t now = systemTime();
14899795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const nsecs_t inSwapBuffers(mDebugInSwapBuffers);
14909795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const nsecs_t inTransaction(mDebugInTransaction);
14919795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0;
14929795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0;
14939795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
14949795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // Try to get the main lock, but don't insist if we can't
14959795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // (this would indicate SF is stuck, but we want to be able to
14969795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // print something in dumpsys).
14979795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        int retry = 3;
14989795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        while (mStateLock.tryLock()<0 && --retry>=0) {
14999795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            usleep(1000000);
15009795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
15019795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const bool locked(retry >= 0);
15029795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (!locked) {
15038b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber            snprintf(buffer, SIZE,
15049795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "SurfaceFlinger appears to be unresponsive, "
15059795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "dumping anyways (no locks held)\n");
15069795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            result.append(buffer);
15079795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
15089795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
150948b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        /*
151048b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian         * Dump the visible layer list
151148b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian         */
1512edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
1513edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const size_t count = currentLayers.size();
151448b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        snprintf(buffer, SIZE, "Visible layers (count = %d)\n", count);
151548b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        result.append(buffer);
1516edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (size_t i=0 ; i<count ; i++) {
15171b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            const sp<LayerBase>& layer(currentLayers[i]);
15181b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            layer->dump(result, buffer, SIZE);
15191b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            const Layer::State& s(layer->drawingState());
1520edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            s.transparentRegion.dump(result, "transparentRegion");
1521edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->transparentRegionScreen.dump(result, "transparentRegionScreen");
1522edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->visibleRegionScreen.dump(result, "visibleRegionScreen");
1523edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
15241b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
152548b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        /*
152648b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian         * Dump the layers in the purgatory
152748b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian         */
152848b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
152948b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        const size_t purgatorySize =  mLayerPurgatory.size();
153048b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        snprintf(buffer, SIZE, "Purgatory state (%d entries)\n", purgatorySize);
153148b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        result.append(buffer);
153248b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        for (size_t i=0 ; i<purgatorySize ; i++) {
153348b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian            const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
153448b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian            layer->shortDump(result, buffer, SIZE);
153548b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        }
153648b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
153748b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        /*
153848b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian         * Dump SurfaceFlinger global state
153948b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian         */
154048b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
1541ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian        snprintf(buffer, SIZE, "SurfaceFlinger global state:\n");
154248b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        result.append(buffer);
1543ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian
1544ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian        const GLExtensions& extensions(GLExtensions::getInstance());
1545ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian        snprintf(buffer, SIZE, "GLES: %s, %s, %s\n",
1546ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian                extensions.getVendor(),
1547ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian                extensions.getRenderer(),
1548ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian                extensions.getVersion());
1549ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian        result.append(buffer);
1550ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian        snprintf(buffer, SIZE, "EXTS: %s\n", extensions.getExtension());
1551ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian        result.append(buffer);
1552ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian
1553edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mWormholeRegion.dump(result, "WormholeRegion");
1554edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const DisplayHardware& hw(graphicPlane(0).displayHardware());
1555edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        snprintf(buffer, SIZE,
1556edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                "  display frozen: %s, freezeCount=%d, orientation=%d, canDraw=%d\n",
1557edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mFreezeDisplay?"yes":"no", mFreezeCount,
1558edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mCurrentState.orientation, hw.canDraw());
1559edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        result.append(buffer);
15609795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        snprintf(buffer, SIZE,
15619795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                "  last eglSwapBuffers() time: %f us\n"
15629795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                "  last transaction time     : %f us\n",
15639795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                mLastSwapBufferTime/1000.0, mLastTransactionTime/1000.0);
15649795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        result.append(buffer);
15651b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
15669795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (inSwapBuffersDuration || !locked) {
15679795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            snprintf(buffer, SIZE, "  eglSwapBuffers time: %f us\n",
15689795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    inSwapBuffersDuration/1000.0);
15699795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            result.append(buffer);
15709795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
15711b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
15729795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (inTransactionDuration || !locked) {
15739795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            snprintf(buffer, SIZE, "  transaction time: %f us\n",
15749795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    inTransactionDuration/1000.0);
15759795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            result.append(buffer);
15769795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
15771b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
157848b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        /*
157948b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian         * Dump HWComposer state
158048b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian         */
158173d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian        HWComposer& hwc(hw.getHwComposer());
158273d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian        snprintf(buffer, SIZE, "  h/w composer %s and %s\n",
158373d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian                hwc.initCheck()==NO_ERROR ? "present" : "not present",
158453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                (mDebugDisableHWC || mDebugRegion) ? "disabled" : "enabled");
158573d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian        result.append(buffer);
15868372785879d329f592f6883620b5a32d80d74691Mathias Agopian        hwc.dump(result, buffer, SIZE);
158773d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian
158848b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        /*
158948b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian         * Dump gralloc state
159048b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian         */
15913330b203039dea366d4981db1408a460134b2d2cMathias Agopian        const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
1592076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        alloc.dump(result);
15931d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling        hw.dump(result);
15949795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
15959795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (locked) {
15969795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            mStateLock.unlock();
15979795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
1598edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1599edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    write(fd, result.string(), result.size());
1600edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1601edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1602edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1603edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::onTransact(
1604edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
1605edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1606edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (code) {
1607edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case CREATE_CONNECTION:
1608698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        case SET_TRANSACTION_STATE:
1609edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case SET_ORIENTATION:
1610edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case FREEZE_DISPLAY:
1611edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case UNFREEZE_DISPLAY:
1612edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case BOOT_FINISHED:
161359119e658a12279e8fff508f8773843de2d90917Mathias Agopian        case TURN_ELECTRON_BEAM_OFF:
16149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        case TURN_ELECTRON_BEAM_ON:
1615edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        {
1616edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // codes that require permission check
1617edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            IPCThreadState* ipc = IPCThreadState::self();
1618edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int pid = ipc->getCallingPid();
1619a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian            const int uid = ipc->getCallingUid();
162099b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
162199b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) {
1622375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                LOGE("Permission Denial: "
1623375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                        "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
1624375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                return PERMISSION_DENIED;
1625edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
16261b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
16271b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
16281b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        case CAPTURE_SCREEN:
16291b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
16301b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            // codes that require permission check
16311b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
16321b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int pid = ipc->getCallingPid();
16331b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int uid = ipc->getCallingUid();
163499b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
163599b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) {
16361b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                LOGE("Permission Denial: "
16371b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                        "can't read framebuffer pid=%d, uid=%d", pid, uid);
16381b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                return PERMISSION_DENIED;
16391b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            }
16401b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
1641edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1642edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
16431b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
1644edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
1645edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
1646b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        CHECK_INTERFACE(ISurfaceComposer, data, reply);
164799b49840d309727678b77403d6cc9f920111623fMathias Agopian        if (UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) {
1648375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
1649375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int pid = ipc->getCallingPid();
1650375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int uid = ipc->getCallingUid();
1651375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            LOGE("Permission Denial: "
1652375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                    "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
1653edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return PERMISSION_DENIED;
1654edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1655edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int n;
1656edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        switch (code) {
165701b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian            case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE
165835b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian            case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE
1659edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1660edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1002:  // SHOW_UPDATES
1661edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                n = data.readInt32();
1662edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDebugRegion = n ? n : (mDebugRegion ? 0 : 1);
166353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
166453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
1665edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1666edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1003:  // SHOW_BACKGROUND
1667edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                n = data.readInt32();
1668edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDebugBackground = n ? 1 : 0;
1669edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1670edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1004:{ // repaint everything
167153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
1672cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
1673cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            }
1674cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            case 1005:{ // force transaction
1675cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
1676cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
1677edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
167835b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian            case 1006:{ // enable/disable GraphicLog
167935b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian                int enabled = data.readInt32();
168035b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian                GraphicLog::getInstance().setEnabled(enabled);
168135b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian                return NO_ERROR;
168235b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian            }
1683edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1007: // set mFreezeCount
1684edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mFreezeCount = data.readInt32();
16850408772e34931351d062f2088b611325ddaa6cdbMathias Agopian                mFreezeDisplayTime = 0;
1686edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
168753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian            case 1008:  // toggle use of hw composer
168853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                n = data.readInt32();
168953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                mDebugDisableHWC = n ? 1 : 0;
169053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
169153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
169253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                return NO_ERROR;
1693a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian            case 1009:  // toggle use of transform hint
1694a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                n = data.readInt32();
1695a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                mDebugDisableTransformHint = n ? 1 : 0;
1696a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                invalidateHwcGeometry();
1697a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                repaintEverything();
1698a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                return NO_ERROR;
1699edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1010:  // interrogate.
170001b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian                reply->writeInt32(0);
1701edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(0);
1702edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(mDebugRegion);
1703edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(mDebugBackground);
1704edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1705edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1013: {
1706edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                Mutex::Autolock _l(mStateLock);
1707edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                const DisplayHardware& hw(graphicPlane(0).displayHardware());
1708edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(hw.getPageFlipCount());
1709edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1710edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return NO_ERROR;
1711edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1712edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1713edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return err;
1714edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1715edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
171653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopianvoid SurfaceFlinger::repaintEverything() {
171753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian    Mutex::Autolock _l(mStateLock);
171853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
171953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian    mDirtyRegion.set(hw.bounds()); // careful that's not thread-safe
172053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian    signalEvent();
172153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian}
172253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian
172359119e658a12279e8fff508f8773843de2d90917Mathias Agopian// ---------------------------------------------------------------------------
172459119e658a12279e8fff508f8773843de2d90917Mathias Agopian
17259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::renderScreenToTextureLocked(DisplayID dpy,
17269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        GLuint* textureName, GLfloat* uOut, GLfloat* vOut)
172759119e658a12279e8fff508f8773843de2d90917Mathias Agopian{
172859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
172959119e658a12279e8fff508f8773843de2d90917Mathias Agopian        return INVALID_OPERATION;
173059119e658a12279e8fff508f8773843de2d90917Mathias Agopian
173159119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // get screen geometry
173259119e658a12279e8fff508f8773843de2d90917Mathias Agopian    const DisplayHardware& hw(graphicPlane(dpy).displayHardware());
173359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    const uint32_t hw_w = hw.getWidth();
173459119e658a12279e8fff508f8773843de2d90917Mathias Agopian    const uint32_t hw_h = hw.getHeight();
173559119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLfloat u = 1;
173659119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLfloat v = 1;
173759119e658a12279e8fff508f8773843de2d90917Mathias Agopian
173859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // make sure to clear all GL error flags
173959119e658a12279e8fff508f8773843de2d90917Mathias Agopian    while ( glGetError() != GL_NO_ERROR ) ;
174059119e658a12279e8fff508f8773843de2d90917Mathias Agopian
174159119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // create a FBO
174259119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLuint name, tname;
174359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glGenTextures(1, &tname);
174459119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
17459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
17469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            hw_w, hw_h, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
174759119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (glGetError() != GL_NO_ERROR) {
1748015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian        while ( glGetError() != GL_NO_ERROR ) ;
174959119e658a12279e8fff508f8773843de2d90917Mathias Agopian        GLint tw = (2 << (31 - clz(hw_w)));
175059119e658a12279e8fff508f8773843de2d90917Mathias Agopian        GLint th = (2 << (31 - clz(hw_h)));
17519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
17529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian                tw, th, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
175359119e658a12279e8fff508f8773843de2d90917Mathias Agopian        u = GLfloat(hw_w) / tw;
175459119e658a12279e8fff508f8773843de2d90917Mathias Agopian        v = GLfloat(hw_h) / th;
175559119e658a12279e8fff508f8773843de2d90917Mathias Agopian    }
175659119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glGenFramebuffersOES(1, &name);
175759119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
17589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES,
17599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0);
176059119e658a12279e8fff508f8773843de2d90917Mathias Agopian
17619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // redraw the screen entirely...
17629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glClearColor(0,0,0,1);
17639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glClear(GL_COLOR_BUFFER_BIT);
17649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
17659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const size_t count = layers.size();
17669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (size_t i=0 ; i<count ; ++i) {
17679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
17689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        layer->drawForSreenShot();
17699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
177059119e658a12279e8fff508f8773843de2d90917Mathias Agopian
17719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // back to main framebuffer
17729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
17739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_SCISSOR_TEST);
17749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDeleteFramebuffersOES(1, &name);
177559119e658a12279e8fff508f8773843de2d90917Mathias Agopian
17769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *textureName = tname;
17779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *uOut = u;
17789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *vOut = v;
17799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
17809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
178159119e658a12279e8fff508f8773843de2d90917Mathias Agopian
17829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// ---------------------------------------------------------------------------
178359119e658a12279e8fff508f8773843de2d90917Mathias Agopian
17849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::electronBeamOffAnimationImplLocked()
17859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
17869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    status_t result = PERMISSION_DENIED;
178759119e658a12279e8fff508f8773843de2d90917Mathias Agopian
17889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
17899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return INVALID_OPERATION;
179059119e658a12279e8fff508f8773843de2d90917Mathias Agopian
17919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // get screen geometry
17929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
17939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_w = hw.getWidth();
17949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_h = hw.getHeight();
17959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const Region screenBounds(hw.bounds());
179659119e658a12279e8fff508f8773843de2d90917Mathias Agopian
17979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat u, v;
17989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLuint tname;
17999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    result = renderScreenToTextureLocked(0, &tname, &u, &v);
18009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (result != NO_ERROR) {
18019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return result;
18029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
180359119e658a12279e8fff508f8773843de2d90917Mathias Agopian
18049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat vtx[8];
1805ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    const GLfloat texCoords[4][2] = { {0,1}, {0,1-v}, {u,1-v}, {u,1} };
18069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
18079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
18089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
18099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
18109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
18119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
18129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glVertexPointer(2, GL_FLOAT, 0, vtx);
18139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
1814ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    /*
1815ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     * Texture coordinate mapping
1816ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *
1817ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *                 u
1818ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *    1 +----------+---+
1819ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |     |    |   |  image is inverted
1820ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |     V    |   |  w.r.t. the texture
1821ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *  1-v +----------+   |  coordinates
1822ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |              |
1823ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |              |
1824ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |              |
1825ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *    0 +--------------+
1826ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      0              1
1827ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *
1828ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     */
1829ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian
18309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class s_curve_interpolator {
18319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float nbFrames, s, v;
18329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
18339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        s_curve_interpolator(int nbFrames, float s)
18349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : nbFrames(1.0f / (nbFrames-1)), s(s),
18359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian          v(1.0f + expf(-s + 0.5f*s)) {
18369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
18379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float operator()(int f) {
18389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const float x = f * nbFrames;
18399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f;
18409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
18419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
18429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
18439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class v_stretch {
18449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
18459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
18469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        v_stretch(uint32_t hw_w, uint32_t hw_h)
18479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
18489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
18499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
18509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w + (hw_w * v);
18519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = hw_h - (hw_h * v);
18529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
18539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
1854ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[0] = x;         vtx[1] = y;
1855ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
1856ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
1857ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
18589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
18599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
18609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
18619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class h_stretch {
18629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
18639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
18649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        h_stretch(uint32_t hw_w, uint32_t hw_h)
18659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
186659119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
18679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
18689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w - (hw_w * v);
18699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = 1.0f;
18709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
18719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
1872ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[0] = x;         vtx[1] = y;
1873ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
1874ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
1875ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
18769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
18779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
18789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
18799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // the full animation is 24 frames
1880ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    char value[PROPERTY_VALUE_MAX];
1881ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    property_get("debug.sf.electron_frames", value, "24");
1882ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    int nbFrames = (atoi(value) + 1) >> 1;
1883ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    if (nbFrames <= 0) // just in case
1884ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian        nbFrames = 24;
1885ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian
18869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itr(nbFrames, 7.5f);
18879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itg(nbFrames, 8.0f);
18889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itb(nbFrames, 8.5f);
18899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
18909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    v_stretch vverts(hw_w, hw_h);
18919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnable(GL_BLEND);
18929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBlendFunc(GL_ONE, GL_ONE);
18939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=0 ; i<nbFrames ; i++) {
18949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float x, y, w, h;
18959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vr = itr(i);
18969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vg = itg(i);
18979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vb = itb(i);
18989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
18999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // clear screen
19009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(1,1,1,1);
19019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
19029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glEnable(GL_TEXTURE_2D);
190359119e658a12279e8fff508f8773843de2d90917Mathias Agopian
19049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the red plane
19059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vr);
19069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(1,0,0,1);
19079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
19089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the green plane
19109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vg);
19119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,1,0,1);
19129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
19139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the blue plane
19159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vb);
19169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,0,1,1);
19179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
19189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the white highlight (we use the last vertices)
192059119e658a12279e8fff508f8773843de2d90917Mathias Agopian        glDisable(GL_TEXTURE_2D);
192159119e658a12279e8fff508f8773843de2d90917Mathias Agopian        glColorMask(1,1,1,1);
19229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColor4f(vg, vg, vg, 1);
19239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
19249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
19259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
19269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    h_stretch hverts(hw_w, hw_h);
19289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_BLEND);
19299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_TEXTURE_2D);
19309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
19319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=0 ; i<nbFrames ; i++) {
19329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float v = itg(i);
19339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hverts(vtx, v);
19349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
19359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColor4f(1-v, 1-v, 1-v, 1);
19369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
19379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
19389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
19399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
19419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnable(GL_SCISSOR_TEST);
19429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
19439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDeleteTextures(1, &tname);
1944a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    glDisable(GL_TEXTURE_2D);
19459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
19469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
19479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::electronBeamOnAnimationImplLocked()
19499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
19509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    status_t result = PERMISSION_DENIED;
19519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
19539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return INVALID_OPERATION;
19549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // get screen geometry
19579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
19589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_w = hw.getWidth();
19599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_h = hw.getHeight();
19609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const Region screenBounds(hw.bounds());
19619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat u, v;
19639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLuint tname;
19649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    result = renderScreenToTextureLocked(0, &tname, &u, &v);
19659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (result != NO_ERROR) {
19669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return result;
19679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
19689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // back to main framebuffer
19709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
19719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_SCISSOR_TEST);
19729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat vtx[8];
19749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const GLfloat texCoords[4][2] = { {0,v}, {0,0}, {u,0}, {u,v} };
19759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
19769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
19779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
19789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
19799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
19809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
19819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glVertexPointer(2, GL_FLOAT, 0, vtx);
19829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class s_curve_interpolator {
19849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float nbFrames, s, v;
19859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
19869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        s_curve_interpolator(int nbFrames, float s)
19879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : nbFrames(1.0f / (nbFrames-1)), s(s),
19889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian          v(1.0f + expf(-s + 0.5f*s)) {
19899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
19909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float operator()(int f) {
19919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const float x = f * nbFrames;
19929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f;
19939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
19949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
19959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class v_stretch {
19979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
19989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
19999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        v_stretch(uint32_t hw_w, uint32_t hw_h)
20009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
200159119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
20029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
20039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w + (hw_w * v);
20049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = hw_h - (hw_h * v);
20059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
20069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
20079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[0] = x;         vtx[1] = y;
20089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
20099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
20109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
20119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
20129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
20139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class h_stretch {
20159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
20169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
20179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        h_stretch(uint32_t hw_w, uint32_t hw_h)
20189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
20199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
20209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
20219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w - (hw_w * v);
20229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = 1.0f;
20239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
20249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
20259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[0] = x;         vtx[1] = y;
20269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
20279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
20289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
20299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
20309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
20319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2032a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian    // the full animation is 12 frames
2033a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian    int nbFrames = 8;
20349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itr(nbFrames, 7.5f);
20359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itg(nbFrames, 8.0f);
20369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itb(nbFrames, 8.5f);
20379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    h_stretch hverts(hw_w, hw_h);
20399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_BLEND);
20409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_TEXTURE_2D);
20419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
20429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=nbFrames-1 ; i>=0 ; i--) {
20439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float v = itg(i);
20449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hverts(vtx, v);
20459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
20469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColor4f(1-v, 1-v, 1-v, 1);
20479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
20489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
20499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
20509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2051a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian    nbFrames = 4;
20529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    v_stretch vverts(hw_w, hw_h);
20539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnable(GL_BLEND);
20549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBlendFunc(GL_ONE, GL_ONE);
20559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=nbFrames-1 ; i>=0 ; i--) {
20569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float x, y, w, h;
20579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vr = itr(i);
20589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vg = itg(i);
20599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vb = itb(i);
206059119e658a12279e8fff508f8773843de2d90917Mathias Agopian
20619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // clear screen
206259119e658a12279e8fff508f8773843de2d90917Mathias Agopian        glColorMask(1,1,1,1);
20639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
20649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glEnable(GL_TEXTURE_2D);
20659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the red plane
20679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vr);
20689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(1,0,0,1);
20699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
20709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the green plane
20729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vg);
20739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,1,0,1);
20749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
20759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the blue plane
20779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vb);
20789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,0,1,1);
20799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
20809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
208259119e658a12279e8fff508f8773843de2d90917Mathias Agopian    }
208359119e658a12279e8fff508f8773843de2d90917Mathias Agopian
20849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
20859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnable(GL_SCISSOR_TEST);
20869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
208759119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glDeleteTextures(1, &tname);
2088a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    glDisable(GL_TEXTURE_2D);
208959119e658a12279e8fff508f8773843de2d90917Mathias Agopian
20909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
20919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
20929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// ---------------------------------------------------------------------------
20949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2095abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOffImplLocked(int32_t mode)
20969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
20979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    DisplayHardware& hw(graphicPlane(0).editDisplayHardware());
20989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (!hw.canDraw()) {
20999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // we're already off
21009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return NO_ERROR;
21019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
2102abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    if (mode & ISurfaceComposer::eElectronBeamAnimationOff) {
2103abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        electronBeamOffAnimationImplLocked();
2104abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    }
2105abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian
2106abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    // always clear the whole screen at the end of the animation
2107abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    glClearColor(0,0,0,1);
2108abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    glDisable(GL_SCISSOR_TEST);
2109abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    glClear(GL_COLOR_BUFFER_BIT);
2110abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    glEnable(GL_SCISSOR_TEST);
2111abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    hw.flip( Region(hw.bounds()) );
2112abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian
2113015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian    hw.setCanDraw(false);
2114015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian    return NO_ERROR;
211559119e658a12279e8fff508f8773843de2d90917Mathias Agopian}
211659119e658a12279e8fff508f8773843de2d90917Mathias Agopian
211759119e658a12279e8fff508f8773843de2d90917Mathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOff(int32_t mode)
211859119e658a12279e8fff508f8773843de2d90917Mathias Agopian{
211959119e658a12279e8fff508f8773843de2d90917Mathias Agopian    class MessageTurnElectronBeamOff : public MessageBase {
212059119e658a12279e8fff508f8773843de2d90917Mathias Agopian        SurfaceFlinger* flinger;
2121abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        int32_t mode;
212259119e658a12279e8fff508f8773843de2d90917Mathias Agopian        status_t result;
212359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    public:
2124abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        MessageTurnElectronBeamOff(SurfaceFlinger* flinger, int32_t mode)
2125abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            : flinger(flinger), mode(mode), result(PERMISSION_DENIED) {
212659119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
212759119e658a12279e8fff508f8773843de2d90917Mathias Agopian        status_t getResult() const {
212859119e658a12279e8fff508f8773843de2d90917Mathias Agopian            return result;
212959119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
213059119e658a12279e8fff508f8773843de2d90917Mathias Agopian        virtual bool handler() {
213159119e658a12279e8fff508f8773843de2d90917Mathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
2132abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            result = flinger->turnElectronBeamOffImplLocked(mode);
213359119e658a12279e8fff508f8773843de2d90917Mathias Agopian            return true;
213459119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
213559119e658a12279e8fff508f8773843de2d90917Mathias Agopian    };
213659119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2137abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    sp<MessageBase> msg = new MessageTurnElectronBeamOff(this, mode);
213859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    status_t res = postMessageSync(msg);
213959119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (res == NO_ERROR) {
214059119e658a12279e8fff508f8773843de2d90917Mathias Agopian        res = static_cast<MessageTurnElectronBeamOff*>( msg.get() )->getResult();
21419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // work-around: when the power-manager calls us we activate the
21439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // animation. eventually, the "on" animation will be called
21449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // by the power-manager itself
2145abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        mElectronBeamAnimationMode = mode;
214659119e658a12279e8fff508f8773843de2d90917Mathias Agopian    }
214759119e658a12279e8fff508f8773843de2d90917Mathias Agopian    return res;
214859119e658a12279e8fff508f8773843de2d90917Mathias Agopian}
214959119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2150edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
2151edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2152abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOnImplLocked(int32_t mode)
21539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
21549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    DisplayHardware& hw(graphicPlane(0).editDisplayHardware());
21559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (hw.canDraw()) {
21569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // we're already on
21579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return NO_ERROR;
21589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
2159abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    if (mode & ISurfaceComposer::eElectronBeamAnimationOn) {
2160abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        electronBeamOnAnimationImplLocked();
2161abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    }
2162015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian    hw.setCanDraw(true);
2163a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian
2164a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian    // make sure to redraw the whole screen when the animation is done
2165a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian    mDirtyRegion.set(hw.bounds());
2166a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian    signalEvent();
2167a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian
2168015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian    return NO_ERROR;
21699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
21709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOn(int32_t mode)
21729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
21739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class MessageTurnElectronBeamOn : public MessageBase {
21749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        SurfaceFlinger* flinger;
2175abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        int32_t mode;
21769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        status_t result;
21779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
2178abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        MessageTurnElectronBeamOn(SurfaceFlinger* flinger, int32_t mode)
2179abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            : flinger(flinger), mode(mode), result(PERMISSION_DENIED) {
21809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
21819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        status_t getResult() const {
21829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return result;
21839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
21849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        virtual bool handler() {
21859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
2186abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            result = flinger->turnElectronBeamOnImplLocked(mode);
21879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return true;
21889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
21899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
21909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2191abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    postMessageAsync( new MessageTurnElectronBeamOn(this, mode) );
21929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
21939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
21949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// ---------------------------------------------------------------------------
21969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
219774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopianstatus_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy,
219874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        sp<IMemoryHeap>* heap,
219974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t* w, uint32_t* h, PixelFormat* f,
2200bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t sw, uint32_t sh,
2201bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ, uint32_t maxLayerZ)
220274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{
220374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    status_t result = PERMISSION_DENIED;
220474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
220574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // only one display supported for now
220674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
220774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return BAD_VALUE;
220874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
22097a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis    // make sure none of the layers are protected
22100abe83a680d1f410c28b755eb4b3d6bee30c39ddMathias Agopian    const LayerVector& layers(mDrawingState.layersSortedByZ);
22117a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis    const size_t count = layers.size();
22127a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis    for (size_t i=0 ; i<count ; ++i) {
22137a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis        const sp<LayerBase>& layer(layers[i]);
2214b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian        const uint32_t flags = layer->drawingState().flags;
2215b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian        if (!(flags & ISurfaceComposer::eLayerHidden)) {
2216b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian            const uint32_t z = layer->drawingState().z;
2217b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian            if (z >= minLayerZ && z <= maxLayerZ) {
2218b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                if (layer->isProtected()) {
2219b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                    return INVALID_OPERATION;
2220b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                }
22217a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis            }
22227a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis        }
22237a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis    }
22247a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis
222574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
222674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return INVALID_OPERATION;
222774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
222874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // get screen geometry
222974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const DisplayHardware& hw(graphicPlane(dpy).displayHardware());
223074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const uint32_t hw_w = hw.getWidth();
223174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const uint32_t hw_h = hw.getHeight();
223274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
223374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    if ((sw > hw_w) || (sh > hw_h))
223474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return BAD_VALUE;
223574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
223674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    sw = (!sw) ? hw_w : sw;
223774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    sh = (!sh) ? hw_h : sh;
223874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const size_t size = sw * sh * 4;
223974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
22401c71a47a6db679a3212f0c99e14f330d6da500faMathias Agopian    //LOGD("screenshot: sw=%d, sh=%d, minZ=%d, maxZ=%d",
22411c71a47a6db679a3212f0c99e14f330d6da500faMathias Agopian    //        sw, sh, minLayerZ, maxLayerZ);
2242c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
224374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // make sure to clear all GL error flags
224474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    while ( glGetError() != GL_NO_ERROR ) ;
224574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
224674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // create a FBO
224774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    GLuint name, tname;
224874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glGenRenderbuffersOES(1, &tname);
224974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindRenderbufferOES(GL_RENDERBUFFER_OES, tname);
225074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA8_OES, sw, sh);
225174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glGenFramebuffersOES(1, &name);
225274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
225374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES,
225474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, tname);
225574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
225674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
2257c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
225874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    if (status == GL_FRAMEBUFFER_COMPLETE_OES) {
225974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
226074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // invert everything, b/c glReadPixel() below will invert the FB
226174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glViewport(0, 0, sw, sh);
2262f653b897a449e10d6cbfb6e0812f7b0bb02d6482Mathias Agopian        glScissor(0, 0, sw, sh);
2263ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian        glEnable(GL_SCISSOR_TEST);
226474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_PROJECTION);
226574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glPushMatrix();
226674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glLoadIdentity();
2267ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian        glOrthof(0, hw_w, hw_h, 0, 0, 1);
226874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_MODELVIEW);
226974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
227074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // redraw the screen entirely...
227174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glClearColor(0,0,0,1);
227274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
2273f653b897a449e10d6cbfb6e0812f7b0bb02d6482Mathias Agopian
227474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        for (size_t i=0 ; i<count ; ++i) {
227574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            const sp<LayerBase>& layer(layers[i]);
2276b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian            const uint32_t flags = layer->drawingState().flags;
2277b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian            if (!(flags & ISurfaceComposer::eLayerHidden)) {
2278b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                const uint32_t z = layer->drawingState().z;
2279b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                if (z >= minLayerZ && z <= maxLayerZ) {
2280b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                    layer->drawForSreenShot();
2281b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                }
2282bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian            }
228374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        }
228474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
228574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // XXX: this is needed on tegra
2286ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian        glEnable(GL_SCISSOR_TEST);
228774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glScissor(0, 0, sw, sh);
228874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
228974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // check for errors and return screen capture
229074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        if (glGetError() != GL_NO_ERROR) {
229174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // error while rendering
229274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            result = INVALID_OPERATION;
229374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        } else {
229474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // allocate shared memory large enough to hold the
229574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // screen capture
229674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            sp<MemoryHeapBase> base(
229774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    new MemoryHeapBase(size, 0, "screen-capture") );
229874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            void* const ptr = base->getBase();
229974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            if (ptr) {
230074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                // capture the screen with glReadPixels()
230174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                glReadPixels(0, 0, sw, sh, GL_RGBA, GL_UNSIGNED_BYTE, ptr);
230274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                if (glGetError() == GL_NO_ERROR) {
230374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *heap = base;
230474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *w = sw;
230574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *h = sh;
230674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *f = PIXEL_FORMAT_RGBA_8888;
230774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    result = NO_ERROR;
230874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                }
230974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            } else {
231074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                result = NO_MEMORY;
231174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            }
231274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        }
231374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glEnable(GL_SCISSOR_TEST);
231474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glViewport(0, 0, hw_w, hw_h);
231574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_PROJECTION);
231674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glPopMatrix();
231774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_MODELVIEW);
231874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    } else {
231974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        result = BAD_VALUE;
232074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    }
232174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
232274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // release FBO resources
232374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
232474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glDeleteRenderbuffersOES(1, &tname);
232574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glDeleteFramebuffersOES(1, &name);
2326e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian
2327e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian    hw.compositionComplete();
2328e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian
23291c71a47a6db679a3212f0c99e14f330d6da500faMathias Agopian    // LOGD("screenshot: result = %s", result<0 ? strerror(result) : "OK");
2330c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
233174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    return result;
233274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian}
233374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
233474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
23351b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopianstatus_t SurfaceFlinger::captureScreen(DisplayID dpy,
23361b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        sp<IMemoryHeap>* heap,
233774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t* width, uint32_t* height, PixelFormat* format,
2338bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t sw, uint32_t sh,
2339bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ, uint32_t maxLayerZ)
23401b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian{
23411b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    // only one display supported for now
23421b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
23431b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        return BAD_VALUE;
23441b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
23451b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
23461b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        return INVALID_OPERATION;
23471b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
23481b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    class MessageCaptureScreen : public MessageBase {
23491b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        SurfaceFlinger* flinger;
23501b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        DisplayID dpy;
23511b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        sp<IMemoryHeap>* heap;
23521b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        uint32_t* w;
23531b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        uint32_t* h;
23541b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        PixelFormat* f;
235574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t sw;
235674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t sh;
2357bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ;
2358bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t maxLayerZ;
23591b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        status_t result;
23601b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    public:
23611b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        MessageCaptureScreen(SurfaceFlinger* flinger, DisplayID dpy,
236274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                sp<IMemoryHeap>* heap, uint32_t* w, uint32_t* h, PixelFormat* f,
2363bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                uint32_t sw, uint32_t sh,
2364bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                uint32_t minLayerZ, uint32_t maxLayerZ)
23651b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            : flinger(flinger), dpy(dpy),
2366bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              heap(heap), w(w), h(h), f(f), sw(sw), sh(sh),
2367bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              minLayerZ(minLayerZ), maxLayerZ(maxLayerZ),
2368bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              result(PERMISSION_DENIED)
23691b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
23701b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
23711b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        status_t getResult() const {
23721b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            return result;
23731b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
23741b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        virtual bool handler() {
23751b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
23761b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
23771b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            // if we have secure windows, never allow the screen capture
23781b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            if (flinger->mSecureFrameBuffer)
23791b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                return true;
23801b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
238174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            result = flinger->captureScreenImplLocked(dpy,
2382bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                    heap, w, h, f, sw, sh, minLayerZ, maxLayerZ);
23831b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
23841b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            return true;
23851b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
23861b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    };
23871b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
23881b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    sp<MessageBase> msg = new MessageCaptureScreen(this,
2389bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian            dpy, heap, width, height, format, sw, sh, minLayerZ, maxLayerZ);
23901b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    status_t res = postMessageSync(msg);
23911b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    if (res == NO_ERROR) {
23921b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        res = static_cast<MessageCaptureScreen*>( msg.get() )->getResult();
23931b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    }
23941b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    return res;
23951b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian}
23961b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
23971b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// ---------------------------------------------------------------------------
23981b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
2399b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<Layer> SurfaceFlinger::getLayer(const sp<ISurface>& sur) const
2400edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2401b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<Layer> result;
2402b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    Mutex::Autolock _l(mStateLock);
2403b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    result = mLayerMap.valueFor( sur->asBinder() ).promote();
2404b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return result;
2405b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
24067303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
2407b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// ---------------------------------------------------------------------------
240896f0819f81293076e652792794a961543e6750d7Mathias Agopian
2409b7e930db175c192464cebdeb49eb56cf6dd60114Mathias AgopianClient::Client(const sp<SurfaceFlinger>& flinger)
2410b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    : mFlinger(flinger), mNameGenerator(1)
2411b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{
2412edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2413edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
241496f0819f81293076e652792794a961543e6750d7Mathias AgopianClient::~Client()
241596f0819f81293076e652792794a961543e6750d7Mathias Agopian{
241696f0819f81293076e652792794a961543e6750d7Mathias Agopian    const size_t count = mLayers.size();
241796f0819f81293076e652792794a961543e6750d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
241896f0819f81293076e652792794a961543e6750d7Mathias Agopian        sp<LayerBaseClient> layer(mLayers.valueAt(i).promote());
241996f0819f81293076e652792794a961543e6750d7Mathias Agopian        if (layer != 0) {
242096f0819f81293076e652792794a961543e6750d7Mathias Agopian            mFlinger->removeLayer(layer);
242196f0819f81293076e652792794a961543e6750d7Mathias Agopian        }
2422edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2423edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2424076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
242596f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t Client::initCheck() const {
2426b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return NO_ERROR;
2427edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2428076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
24294f113740180b6512b43723c4728f262882dc9b45Mathias Agopiansize_t Client::attachLayer(const sp<LayerBaseClient>& layer)
2430edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
24314f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    Mutex::Autolock _l(mLock);
24324f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    size_t name = mNameGenerator++;
243396f0819f81293076e652792794a961543e6750d7Mathias Agopian    mLayers.add(name, layer);
243496f0819f81293076e652792794a961543e6750d7Mathias Agopian    return name;
2435edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2436edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2437b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianvoid Client::detachLayer(const LayerBaseClient* layer)
243896f0819f81293076e652792794a961543e6750d7Mathias Agopian{
24394f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    Mutex::Autolock _l(mLock);
244096f0819f81293076e652792794a961543e6750d7Mathias Agopian    // we do a linear search here, because this doesn't happen often
244196f0819f81293076e652792794a961543e6750d7Mathias Agopian    const size_t count = mLayers.size();
244296f0819f81293076e652792794a961543e6750d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
244396f0819f81293076e652792794a961543e6750d7Mathias Agopian        if (mLayers.valueAt(i) == layer) {
244496f0819f81293076e652792794a961543e6750d7Mathias Agopian            mLayers.removeItemsAt(i, 1);
244596f0819f81293076e652792794a961543e6750d7Mathias Agopian            break;
244696f0819f81293076e652792794a961543e6750d7Mathias Agopian        }
244796f0819f81293076e652792794a961543e6750d7Mathias Agopian    }
244896f0819f81293076e652792794a961543e6750d7Mathias Agopian}
24494f113740180b6512b43723c4728f262882dc9b45Mathias Agopiansp<LayerBaseClient> Client::getLayerUser(int32_t i) const
24504f113740180b6512b43723c4728f262882dc9b45Mathias Agopian{
24514f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    Mutex::Autolock _l(mLock);
2452076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBaseClient> lbc;
24534f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    wp<LayerBaseClient> layer(mLayers.valueFor(i));
245496f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (layer != 0) {
245596f0819f81293076e652792794a961543e6750d7Mathias Agopian        lbc = layer.promote();
245696f0819f81293076e652792794a961543e6750d7Mathias Agopian        LOGE_IF(lbc==0, "getLayerUser(name=%d) is dead", int(i));
2457076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
2458076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return lbc;
2459edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2460edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2461a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
2462a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianstatus_t Client::onTransact(
2463a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
2464a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian{
2465a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // these must be checked
2466a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     IPCThreadState* ipc = IPCThreadState::self();
2467a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     const int pid = ipc->getCallingPid();
2468a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     const int uid = ipc->getCallingUid();
2469a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     const int self_pid = getpid();
2470a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     if (UNLIKELY(pid != self_pid && uid != AID_GRAPHICS && uid != 0)) {
2471a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian         // we're called from a different process, do the real check
247299b49840d309727678b77403d6cc9f920111623fMathias Agopian         if (!PermissionCache::checkCallingPermission(sAccessSurfaceFlinger))
2473a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian         {
2474a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian             LOGE("Permission Denial: "
2475a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                     "can't openGlobalTransaction pid=%d, uid=%d", pid, uid);
2476a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian             return PERMISSION_DENIED;
2477a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian         }
2478a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     }
2479a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     return BnSurfaceComposerClient::onTransact(code, data, reply, flags);
2480edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2481a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
2482a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
248396f0819f81293076e652792794a961543e6750d7Mathias Agopiansp<ISurface> Client::createSurface(
24840ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        ISurfaceComposerClient::surface_data_t* params,
2485b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        const String8& name,
2486b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
2487edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t flags)
2488edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2489b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    /*
2490a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     * createSurface must be called from the GL thread so that it can
2491a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     * have access to the GL context.
2492b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     */
2493b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
2494a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    class MessageCreateSurface : public MessageBase {
2495a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        sp<ISurface> result;
2496a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        SurfaceFlinger* flinger;
2497a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        ISurfaceComposerClient::surface_data_t* params;
2498a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        Client* client;
2499a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        const String8& name;
2500a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        DisplayID display;
2501a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        uint32_t w, h;
2502a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        PixelFormat format;
2503a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        uint32_t flags;
2504a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    public:
2505a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        MessageCreateSurface(SurfaceFlinger* flinger,
2506a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                ISurfaceComposerClient::surface_data_t* params,
2507a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                const String8& name, Client* client,
2508a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
2509a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                uint32_t flags)
2510a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            : flinger(flinger), params(params), client(client), name(name),
2511a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian              display(display), w(w), h(h), format(format), flags(flags)
2512a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        {
2513579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        }
2514a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        sp<ISurface> getResult() const { return result; }
2515a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        virtual bool handler() {
2516a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            result = flinger->createSurface(params, name, client,
2517a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                    display, w, h, format, flags);
2518a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            return true;
2519b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        }
2520a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    };
2521b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
2522a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    sp<MessageBase> msg = new MessageCreateSurface(mFlinger.get(),
2523a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            params, name, this, display, w, h, format, flags);
2524a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    mFlinger->postMessageSync(msg);
2525a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    return static_cast<MessageCreateSurface*>( msg.get() )->getResult();
2526b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
2527a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianstatus_t Client::destroySurface(SurfaceID sid) {
2528a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    return mFlinger->removeSurface(this, sid);
2529b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
2530b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
2531b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// ---------------------------------------------------------------------------
2532edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
25339a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::GraphicBufferAlloc() {}
25349a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
25359a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::~GraphicBufferAlloc() {}
25369a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
25379a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h,
2538d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        PixelFormat format, uint32_t usage, status_t* error) {
25399a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(w, h, format, usage));
25409a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    status_t err = graphicBuffer->initCheck();
2541d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian    *error = err;
2542a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (err != 0 || graphicBuffer->handle == 0) {
2543d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        if (err == NO_MEMORY) {
2544d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian            GraphicBuffer::dumpAllocationsToSystemLog();
2545d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        }
2546a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        LOGE("GraphicBufferAlloc::createGraphicBuffer(w=%d, h=%d) "
2547a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian             "failed (%s), handle=%p",
2548a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                w, h, strerror(-err), graphicBuffer->handle);
25499a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis        return 0;
25509a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    }
25519a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    return graphicBuffer;
25529a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis}
25539a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
25549a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis// ---------------------------------------------------------------------------
25559a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
2556edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane::GraphicPlane()
2557edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    : mHw(0)
2558edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2559edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2560edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2561edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane::~GraphicPlane() {
2562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    delete mHw;
2563edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2564edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2565edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool GraphicPlane::initialized() const {
2566edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return mHw ? true : false;
2567edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2568edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
25692b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianint GraphicPlane::getWidth() const {
25702b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    return mWidth;
2571edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2572edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
25732b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianint GraphicPlane::getHeight() const {
25742b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    return mHeight;
25752b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian}
25762b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
25772b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianvoid GraphicPlane::setDisplayHardware(DisplayHardware *hw)
25782b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian{
25792b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mHw = hw;
25802b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
25812b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    // initialize the display orientation transform.
25822b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    // it's a constant that should come from the display driver.
25832b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    int displayOrientation = ISurfaceComposer::eOrientationDefault;
25842b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    char property[PROPERTY_VALUE_MAX];
25852b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    if (property_get("ro.sf.hwrotation", property, NULL) > 0) {
25862b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        //displayOrientation
25872b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        switch (atoi(property)) {
25882b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        case 90:
25892b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            displayOrientation = ISurfaceComposer::eOrientation90;
25902b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            break;
25912b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        case 270:
25922b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            displayOrientation = ISurfaceComposer::eOrientation270;
25932b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            break;
25942b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        }
25952b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    }
25962b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
25972b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float w = hw->getWidth();
25982b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float h = hw->getHeight();
25992b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    GraphicPlane::orientationToTransfrom(displayOrientation, w, h,
26002b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            &mDisplayTransform);
26012b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    if (displayOrientation & ISurfaceComposer::eOrientationSwapMask) {
26022b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayWidth = h;
26032b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayHeight = w;
26042b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    } else {
26052b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayWidth = w;
26062b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayHeight = h;
26072b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    }
26082b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
26092b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    setOrientation(ISurfaceComposer::eOrientationDefault);
2610edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2611edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2612edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t GraphicPlane::orientationToTransfrom(
2613edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int orientation, int w, int h, Transform* tr)
2614eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian{
2615eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    uint32_t flags = 0;
2616edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (orientation) {
2617edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientationDefault:
2618eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_0;
2619eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        break;
2620edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientation90:
2621eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_90;
2622edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
2623edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientation180:
2624eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_180;
2625edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
2626edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientation270:
2627eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_270;
2628edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
2629edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    default:
2630edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return BAD_VALUE;
2631edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2632eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    tr->set(flags, w, h);
2633edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
2634edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2635edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2636edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t GraphicPlane::setOrientation(int orientation)
2637edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2638edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // If the rotation can be handled in hardware, this is where
2639edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // the magic should happen.
26402b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
26412b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const DisplayHardware& hw(displayHardware());
26422b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float w = mDisplayWidth;
26432b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float h = mDisplayHeight;
26442b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mWidth = int(w);
26452b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mHeight = int(h);
26462b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
26472b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    Transform orientationTransform;
2648eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    GraphicPlane::orientationToTransfrom(orientation, w, h,
2649eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian            &orientationTransform);
2650eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    if (orientation & ISurfaceComposer::eOrientationSwapMask) {
2651eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        mWidth = int(h);
2652eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        mHeight = int(w);
2653edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2654eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian
26550d1318b974feba2e6ff13e36a1781343c2fce045Mathias Agopian    mOrientation = orientation;
26562b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mGlobalTransform = mDisplayTransform * orientationTransform;
2657edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
2658edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2659edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2660edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst DisplayHardware& GraphicPlane::displayHardware() const {
2661edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return *mHw;
2662edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2663edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
266459119e658a12279e8fff508f8773843de2d90917Mathias AgopianDisplayHardware& GraphicPlane::editDisplayHardware() {
266559119e658a12279e8fff508f8773843de2d90917Mathias Agopian    return *mHw;
266659119e658a12279e8fff508f8773843de2d90917Mathias Agopian}
266759119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2668edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst Transform& GraphicPlane::transform() const {
2669edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return mGlobalTransform;
2670edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2671edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2672076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias AgopianEGLDisplay GraphicPlane::getEGLDisplay() const {
2673076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return mHw->getEGLDisplay();
2674076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
2675076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
2676edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
2677edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2678edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
2679