SurfaceFlinger.cpp revision 35aadd6be249da4bd4851692e6aff757c91b32a7
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
171c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#define ATRACE_TAG ATRACE_TAG_GRAPHICS
181c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
19edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdlib.h>
20edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdio.h>
21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdint.h>
22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <unistd.h>
23edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <fcntl.h>
24edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <errno.h>
25edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <math.h>
26a837ba778f2d7a5170b37aa33624d9b9711c354dJean-Baptiste Queru#include <limits.h>
27edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/types.h>
28edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/stat.h>
29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/ioctl.h>
30edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/log.h>
32edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/properties.h>
33edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
34c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IPCThreadState.h>
35c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IServiceManager.h>
367303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian#include <binder/MemoryHeapBase.h>
3799b49840d309727678b77403d6cc9f920111623fMathias Agopian#include <binder/PermissionCache.h>
387303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
39d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian#include <gui/IDisplayEventConnection.h>
40d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
41edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String8.h>
42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String16.h>
43edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/StopWatch.h>
441c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#include <utils/Trace.h>
45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
463330b203039dea366d4981db1408a460134b2d2cMathias Agopian#include <ui/GraphicBufferAllocator.h>
47edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/PixelFormat.h>
48edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <GLES/gl.h>
50edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h"
5290ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include "DdmConnection.h"
53d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian#include "DisplayEventConnection.h"
54d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian#include "EventThread.h"
551f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian#include "GLExtensions.h"
56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h"
57edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerDim.h"
58118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian#include "LayerScreenshot.h"
59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h"
60edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
61edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "DisplayHardware/DisplayHardware.h"
62a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian#include "DisplayHardware/HWComposer.h"
63edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
641db13d79518f600d65a4fc006fe42900b890966eGlenn Kasten#include <private/android_filesystem_config.h>
6590ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include <private/gui/SharedBufferStack.h>
66a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
67bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian#define EGL_VERSION_HW_ANDROID  0x3143
68bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DISPLAY_COUNT       1
70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
73edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
7499b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sHardwareTest("android.permission.HARDWARE_TEST");
7599b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER");
7699b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER");
7799b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sDump("android.permission.DUMP");
7899b49840d309727678b77403d6cc9f920111623fMathias Agopian
7999b49840d309727678b77403d6cc9f920111623fMathias Agopian// ---------------------------------------------------------------------------
8099b49840d309727678b77403d6cc9f920111623fMathias Agopian
81edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::SurfaceFlinger()
82edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    :   BnSurfaceComposer(), Thread(false),
83edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mTransactionFlags(0),
8428378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        mTransationPending(false),
85076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved(false),
86edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mBootTime(systemTime()),
87edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mVisibleRegionsDirty(false),
88a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        mHwWorkListDirty(false),
89abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        mElectronBeamAnimationMode(0),
90edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDebugRegion(0),
91edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDebugBackground(0),
928afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian        mDebugDDMS(0),
9373d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian        mDebugDisableHWC(0),
94a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian        mDebugDisableTransformHint(0),
959795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInSwapBuffers(0),
969795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastSwapBufferTime(0),
979795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInTransaction(0),
989795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastTransactionTime(0),
993330b203039dea366d4981db1408a460134b2d2cMathias Agopian        mBootFinished(false),
100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mConsoleSignals(0),
101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mSecureFrameBuffer(0)
102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    init();
104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::init()
107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
108a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI("SurfaceFlinger is starting");
109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // debugging stuff...
111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char value[PROPERTY_VALUE_MAX];
1128afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
113edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    property_get("debug.sf.showupdates", value, "0");
114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDebugRegion = atoi(value);
1158afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    property_get("debug.sf.showbackground", value, "0");
117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDebugBackground = atoi(value);
118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1198afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    property_get("debug.sf.ddms", value, "0");
1208afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    mDebugDDMS = atoi(value);
1218afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    if (mDebugDDMS) {
1228afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian        DdmConnection::start(getServiceName());
1238afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    }
1248afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
125a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI_IF(mDebugRegion,       "showupdates enabled");
126a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI_IF(mDebugBackground,   "showbackground enabled");
127a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI_IF(mDebugDDMS,         "DDMS debugging enabled");
128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
13099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::onFirstRef()
13199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
13299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.init(this);
13399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
13499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY);
13599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
13699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // Wait for the main thread to be done with its initialization
13799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mReadyToRunBarrier.wait();
13899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
13999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
14099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
141edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::~SurfaceFlinger()
142edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
143edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDeleteTextures(1, &mWormholeTexName);
144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
145edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
14699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::binderDied(const wp<IBinder>& who)
14799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
14899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // the window manager died on us. prepare its eulogy.
14999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
15099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // reset screen orientation
15199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    Vector<ComposerState> state;
15299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    setTransactionState(state, eOrientationDefault, 0);
15399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
15499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // restart the boot-animation
15599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    property_set("ctl.start", "bootanim");
15699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
15799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
1587303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopiansp<IMemoryHeap> SurfaceFlinger::getCblk() const
159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1607303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    return mServerHeap;
161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1637e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopiansp<ISurfaceComposerClient> SurfaceFlinger::createConnection()
164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
16596f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<ISurfaceComposerClient> bclient;
16696f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<Client> client(new Client(this));
16796f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = client->initCheck();
16896f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR) {
16996f0819f81293076e652792794a961543e6750d7Mathias Agopian        bclient = client;
170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return bclient;
172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1749a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc()
1759a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis{
1769a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc());
1779a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    return gba;
1789a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis}
179b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst GraphicPlane& SurfaceFlinger::graphicPlane(int dpy) const
181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
182e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block    ALOGE_IF(uint32_t(dpy) >= DISPLAY_COUNT, "Invalid DisplayID %d", dpy);
183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(mGraphicPlanes[dpy]);
184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return plane;
185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane& SurfaceFlinger::graphicPlane(int dpy)
188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return const_cast<GraphicPlane&>(
190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const_cast<SurfaceFlinger const *>(this)->graphicPlane(dpy));
191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::bootFinished()
194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
195edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t now = systemTime();
196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t duration = now - mBootTime;
197a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
1983330b203039dea366d4981db1408a460134b2d2cMathias Agopian    mBootFinished = true;
1991f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
2001f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // wait patiently for the window manager death
2011f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    const String16 name("window");
2021f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    sp<IBinder> window(defaultServiceManager()->getService(name));
2031f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    if (window != 0) {
2041f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian        window->linkToDeath(this);
2051f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    }
2061f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
2071f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // stop boot animation
208a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    property_set("ctl.stop", "bootanim");
209edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
210edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic inline uint16_t pack565(int r, int g, int b) {
212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return (r<<11)|(g<<5)|b;
213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::readyToRun()
216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
217a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI(   "SurfaceFlinger's main thread ready to run. "
218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            "Initializing graphics H/W...");
219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // we only support one display currently
221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int dpy = 0;
222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    {
224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // initialize the main display
225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GraphicPlane& plane(graphicPlane(dpy));
226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        DisplayHardware* const hw = new DisplayHardware(this, dpy);
227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        plane.setDisplayHardware(hw);
228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2307303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    // create the shared control-block
2317303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    mServerHeap = new MemoryHeapBase(4096,
2327303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian            MemoryHeapBase::READ_ONLY, "SurfaceFlinger read-only heap");
233e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block    ALOGE_IF(mServerHeap==0, "can't create shared memory dealer");
2348b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
2357303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    mServerCblk = static_cast<surface_flinger_cblk_t*>(mServerHeap->getBase());
236e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block    ALOGE_IF(mServerCblk==0, "can't get to shared control block's address");
2378b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
2387303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    new(mServerCblk) surface_flinger_cblk_t;
2397303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize primary screen
241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // (other display should be initialized in the same manner, but
242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // asynchronously, as they could come and go. None of this is supported
243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // yet).
244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(graphicPlane(dpy));
245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw = plane.displayHardware();
246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint32_t w = hw.getWidth();
247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint32_t h = hw.getHeight();
248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint32_t f = hw.getFormat();
249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    hw.makeCurrent();
250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize the shared control block
252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mServerCblk->connected |= 1<<dpy;
253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    display_cblk_t* dcblk = mServerCblk->displays + dpy;
254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    memset(dcblk, 0, sizeof(display_cblk_t));
2552b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    dcblk->w            = plane.getWidth();
2562b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    dcblk->h            = plane.getHeight();
257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->format       = f;
258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->orientation  = ISurfaceComposer::eOrientationDefault;
259edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->xdpi         = hw.getDpiX();
260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->ydpi         = hw.getDpiY();
261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->fps          = hw.getRefreshRate();
262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->density      = hw.getDensity();
263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // Initialize OpenGL|ES
265edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
2668b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber    glPixelStorei(GL_PACK_ALIGNMENT, 4);
267edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glEnableClientState(GL_VERTEX_ARRAY);
268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glEnable(GL_SCISSOR_TEST);
269edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glShadeModel(GL_FLAT);
270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_DITHER);
271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_CULL_FACE);
272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint16_t g0 = pack565(0x0F,0x1F,0x0F);
274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint16_t g1 = pack565(0x17,0x2f,0x17);
2759575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    const uint16_t wormholeTexData[4] = { g0, g1, g1, g0 };
276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glGenTextures(1, &mWormholeTexName);
277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glBindTexture(GL_TEXTURE_2D, mWormholeTexName);
278edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0,
2839575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis            GL_RGB, GL_UNSIGNED_SHORT_5_6_5, wormholeTexData);
2849575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis
2859575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    const uint16_t protTexData[] = { pack565(0x03, 0x03, 0x03) };
2869575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glGenTextures(1, &mProtectedTexName);
2879575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glBindTexture(GL_TEXTURE_2D, mProtectedTexName);
2889575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2899575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2909575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
2919575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
2929575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0,
2939575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis            GL_RGB, GL_UNSIGNED_SHORT_5_6_5, protTexData);
294edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
295edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glViewport(0, 0, w, h);
296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glMatrixMode(GL_PROJECTION);
297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glLoadIdentity();
298ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    // put the origin in the left-bottom corner
299ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    glOrthof(0, w, 0, h, 0, 1); // l=0, r=w ; b=0, t=h
300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
301d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
302d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian    // start the EventThread
303d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian    mEventThread = new EventThread(this);
3048aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian    mEventQueue.setEventThread(mEventThread);
305f6de1c04ffc2c7a739578b7612944fddb7011ab7Mathias Agopian    hw.startSleepManagement();
306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     *  We're now ready to accept clients...
309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
310edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
311d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian    mReadyToRunBarrier.open();
312d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
313a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    // start boot animation
314a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    property_set("ctl.start", "bootanim");
3158b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
320d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
321582270d69db94286a248bd829f1ae6f910d45124Jamie Gennisbool SurfaceFlinger::authenticateSurfaceTexture(
322582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis        const sp<ISurfaceTexture>& surfaceTexture) const {
323134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    Mutex::Autolock _l(mStateLock);
324582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis    sp<IBinder> surfaceTextureBinder(surfaceTexture->asBinder());
325134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
326134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // Check the visible layer list for the ISurface
327134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
328134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    size_t count = currentLayers.size();
329134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    for (size_t i=0 ; i<count ; i++) {
330134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        const sp<LayerBase>& layer(currentLayers[i]);
331134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        sp<LayerBaseClient> lbc(layer->getLayerBaseClient());
332582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis        if (lbc != NULL) {
333582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder();
334582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            if (lbcBinder == surfaceTextureBinder) {
335582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis                return true;
336582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            }
337134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        }
338134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    }
339134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
340134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // Check the layers in the purgatory.  This check is here so that if a
341582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis    // SurfaceTexture gets destroyed before all the clients are done using it,
342582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis    // the error will not be reported as "surface XYZ is not authenticated", but
343134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // will instead fail later on when the client tries to use the surface,
344134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // which should be reported as "surface XYZ returned an -ENODEV".  The
345134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // purgatorized layers are no less authentic than the visible ones, so this
346134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // should not cause any harm.
347134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    size_t purgatorySize =  mLayerPurgatory.size();
348134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    for (size_t i=0 ; i<purgatorySize ; i++) {
349134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
350134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        sp<LayerBaseClient> lbc(layer->getLayerBaseClient());
351582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis        if (lbc != NULL) {
352582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder();
353582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            if (lbcBinder == surfaceTextureBinder) {
354582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis                return true;
355582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            }
356134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        }
357134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    }
358134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
359134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    return false;
360134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis}
361134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
362d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian// ----------------------------------------------------------------------------
363d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
364d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopiansp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection() {
3658aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian    return mEventThread->createEventConnection();
366bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian}
367bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
368edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
36999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
37099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::waitForEvent() {
37199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.waitMessage();
37299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
37399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
37499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalTransaction() {
37599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.invalidate();
37699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
37799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
37899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalLayerUpdate() {
37999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.invalidate();
38099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
38199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
38299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalRefresh() {
38399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.refresh();
38499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
38599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
38699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg,
38799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        nsecs_t reltime, uint32_t flags) {
38899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return mEventQueue.postMessage(msg, reltime);
38999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
39099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
39199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,
39299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        nsecs_t reltime, uint32_t flags) {
39399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    status_t res = mEventQueue.postMessage(msg, reltime);
39499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    if (res == NO_ERROR) {
39599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        msg->wait();
39699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    }
39799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return res;
39899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
399edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
400edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool SurfaceFlinger::threadLoop()
401edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
402edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    waitForEvent();
40399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return true;
40499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
405edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
40699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::onMessageReceived(int32_t what)
40799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
4081c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
40999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    switch (what) {
410303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian        case MessageQueue::REFRESH: {
411303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian//        case MessageQueue::INVALIDATE: {
41299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            // check for transactions
41399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            if (CC_UNLIKELY(mConsoleSignals)) {
41499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian                handleConsoleEvents();
41599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            }
416edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
41799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            // if we're in a global transaction, don't do anything.
41899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
41999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            uint32_t transactionFlags = peekTransactionFlags(mask);
42099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            if (CC_UNLIKELY(transactionFlags)) {
42199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian                handleTransaction(transactionFlags);
42299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            }
423edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
42499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            // post surfaces (if needed)
42599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            handlePageFlip();
426edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
427303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian//            signalRefresh();
428303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian//
429303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian//        } break;
430303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian//
431303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian//        case MessageQueue::REFRESH: {
4323a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian
433c9ca7011501cb8730ce4e6e527cb402adb7a0178Mathias Agopian            handleRefresh();
434a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
435303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian            const DisplayHardware& hw(graphicPlane(0).displayHardware());
436303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian
437303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian//            if (mDirtyRegion.isEmpty()) {
438303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian//                return;
439303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian//            }
440303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian
441b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian            if (CC_UNLIKELY(mHwWorkListDirty)) {
442b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian                // build the h/w work list
443b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian                handleWorkList();
444b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian            }
445303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian
446b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian            if (CC_LIKELY(hw.canDraw())) {
447b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian                // repaint the framebuffer (if needed)
448b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian                handleRepaint();
449b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian                // inform the h/w that we're done compositing
450b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian                hw.compositionComplete();
451b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian                postFramebuffer();
452c9ca7011501cb8730ce4e6e527cb402adb7a0178Mathias Agopian            } else {
453b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian                // pretend we did the post
454c9ca7011501cb8730ce4e6e527cb402adb7a0178Mathias Agopian                hw.compositionComplete();
45599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            }
456b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian
45799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        } break;
458edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
459edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
460edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
461edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer()
462edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
463841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
464b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian    // mSwapRegion can be empty here is some cases, for instance if a hidden
465b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian    // or fully transparent window is updating.
466b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian    // in that case, we need to flip anyways to not risk a deadlock with
467b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian    // h/w composer.
468b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian
469a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
470a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    const nsecs_t now = systemTime();
471a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = now;
472a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    hw.flip(mSwapRegion);
473e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
474e8696a40e09b24b634214684d18526187b316a2fJamie Gennis    size_t numLayers = mVisibleLayersSortedByZ.size();
475e8696a40e09b24b634214684d18526187b316a2fJamie Gennis    for (size_t i = 0; i < numLayers; i++) {
476e8696a40e09b24b634214684d18526187b316a2fJamie Gennis        mVisibleLayersSortedByZ[i]->onLayerDisplayed();
477e8696a40e09b24b634214684d18526187b316a2fJamie Gennis    }
478e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
479a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mLastSwapBufferTime = systemTime() - now;
480a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = 0;
481a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mSwapRegion.clear();
482edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
483edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
484edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleConsoleEvents()
485edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
486edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // something to do with the console
487edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw = graphicPlane(0).displayHardware();
488edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
489edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int what = android_atomic_and(0, &mConsoleSignals);
490edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (what & eConsoleAcquired) {
491edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        hw.acquireScreen();
4929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // this is a temporary work-around, eventually this should be called
4939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // by the power-manager
494abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        SurfaceFlinger::turnElectronBeamOn(mElectronBeamAnimationMode);
495edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
496edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
497edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (what & eConsoleReleased) {
49859119e658a12279e8fff508f8773843de2d90917Mathias Agopian        if (hw.isScreenAcquired()) {
499edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            hw.releaseScreen();
500edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
501edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
502edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
503edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDirtyRegion.set(hw.bounds());
504edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
505edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
506edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
507edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
508841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
509841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
510ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    Mutex::Autolock _l(mStateLock);
511ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    const nsecs_t now = systemTime();
512ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = now;
513ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
514ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // Here we're guaranteed that some transaction flags are set
515ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // so we can call handleTransactionLocked() unconditionally.
516ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // We call getTransactionFlags(), which will also clear the flags,
517ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // with mStateLock held to guarantee that mCurrentState won't change
518ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // until the transaction is committed.
519ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
520ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
521ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    transactionFlags = getTransactionFlags(mask);
522ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    handleTransactionLocked(transactionFlags);
523ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
524ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mLastTransactionTime = systemTime() - now;
525ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = 0;
526ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    invalidateHwcGeometry();
527ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // here the transaction has been committed
5283d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian}
529edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
530ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopianvoid SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
5313d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{
5323d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    const LayerVector& currentLayers(mCurrentState.layersSortedByZ);
533edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t count = currentLayers.size();
534edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
535edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
536edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Traversal of the children
537edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * (perform the transaction for each of them if needed)
538edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
539edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
540edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const bool layersNeedTransaction = transactionFlags & eTraversalNeeded;
541edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (layersNeedTransaction) {
542edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (size_t i=0 ; i<count ; i++) {
543076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            const sp<LayerBase>& layer = currentLayers[i];
544edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
545edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (!trFlags) continue;
546edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
547edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const uint32_t flags = layer->doTransaction(0);
548edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (flags & Layer::eVisibleRegion)
549edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mVisibleRegionsDirty = true;
550edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
551edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
552edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
553edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
554edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Perform our own transaction if needed
555edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
556edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
557edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (transactionFlags & eTransactionNeeded) {
558edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (mCurrentState.orientation != mDrawingState.orientation) {
559edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // the orientation has changed, recompute all visible regions
560edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // and invalidate everything.
561edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int dpy = 0;
563edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int orientation = mCurrentState.orientation;
56421230c6410bdab13cd2bd274da54b1e4061b6035Jeff Brown            // Currently unused: const uint32_t flags = mCurrentState.orientationFlags;
565edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            GraphicPlane& plane(graphicPlane(dpy));
566edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            plane.setOrientation(orientation);
567edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
568edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // update the shared control block
569edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const DisplayHardware& hw(plane.displayHardware());
570edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            volatile display_cblk_t* dcblk = mServerCblk->displays + dpy;
571edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dcblk->orientation = orientation;
5722b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            dcblk->w = plane.getWidth();
5732b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            dcblk->h = plane.getHeight();
574edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
575edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
576edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mDirtyRegion.set(hw.bounds());
577edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
578edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5790aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        if (currentLayers.size() > mDrawingState.layersSortedByZ.size()) {
5800aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            // layers have been added
581edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
582edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
583edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5840aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        // some layers might have been removed, so
5850aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        // we need to update the regions they're exposing.
5860aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        if (mLayersRemoved) {
58748d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian            mLayersRemoved = false;
588edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
5890aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            const LayerVector& previousLayers(mDrawingState.layersSortedByZ);
5903d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian            const size_t count = previousLayers.size();
5913d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian            for (size_t i=0 ; i<count ; i++) {
5920aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                const sp<LayerBase>& layer(previousLayers[i]);
5930aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                if (currentLayers.indexOf( layer ) < 0) {
5940aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                    // this layer is not visible anymore
5955d7126b625c8c4a7b945e8c247b63abff7bc13b6Mathias Agopian                    mDirtyRegionRemovedLayer.orSelf(layer->visibleRegionScreen);
5960aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                }
5970aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            }
598edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
599edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
600edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
601edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    commitTransaction();
602edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
603edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
604edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::computeVisibleRegions(
6051bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian    const LayerVector& currentLayers, Region& dirtyRegion, Region& opaqueRegion)
606edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
607841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
608841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
609edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(graphicPlane(0));
610edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Transform& planeTransform(plane.transform());
611ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian    const DisplayHardware& hw(plane.displayHardware());
612ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian    const Region screenRegion(hw.bounds());
613edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
614edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveOpaqueLayers;
615edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveCoveredLayers;
616edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region dirty;
617edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
618edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    bool secureFrameBuffer = false;
619edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
620edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t i = currentLayers.size();
621edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    while (i--) {
622076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        const sp<LayerBase>& layer = currentLayers[i];
623edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->validateVisibility(planeTransform);
624edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
625edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // start with the whole surface at its current location
626970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian        const Layer::State& s(layer->drawingState());
627edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
628ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
629ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * opaqueRegion: area of a surface that is fully opaque.
630ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
631edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region opaqueRegion;
632ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
633ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
634ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visibleRegion: area of a surface that is visible on screen
635ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * and not fully transparent. This is essentially the layer's
636ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * footprint minus the opaque regions above it.
637ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * Areas covered by a translucent surface are considered visible.
638ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
639edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region visibleRegion;
640ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
641ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
642ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * coveredRegion: area of a surface that is covered by all
643ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visible regions above it (which includes the translucent areas).
644ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
645edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region coveredRegion;
646ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
647ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
648ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // handle hidden surfaces by setting the visible region to empty
64999ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten        if (CC_LIKELY(!(s.flags & ISurfaceComposer::eLayerHidden) && s.alpha)) {
650a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            const bool translucent = !layer->isOpaque();
651970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian            const Rect bounds(layer->visibleBounds());
652edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            visibleRegion.set(bounds);
653ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            visibleRegion.andSelf(screenRegion);
654ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            if (!visibleRegion.isEmpty()) {
655ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // Remove the transparent area from the visible region
656ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (translucent) {
657ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    visibleRegion.subtractSelf(layer->transparentRegionScreen);
658ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
659edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
660ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // compute the opaque region
661ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                const int32_t layerOrientation = layer->getOrientation();
662ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (s.alpha==255 && !translucent &&
663ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                        ((layerOrientation & Transform::ROT_INVALID) == false)) {
664ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    // the opaque region is the layer's footprint
665ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    opaqueRegion = visibleRegion;
666ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
667edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
668edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
669edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
670ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Clip the covered region to the visible region
671ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        coveredRegion = aboveCoveredLayers.intersect(visibleRegion);
672ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
673ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveCoveredLayers for next (lower) layer
674ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        aboveCoveredLayers.orSelf(visibleRegion);
675ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
676edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // subtract the opaque region covered by the layers above us
677edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        visibleRegion.subtractSelf(aboveOpaqueLayers);
678edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
679edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // compute this layer's dirty region
680edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (layer->contentDirty) {
681edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // we need to invalidate the whole region
682edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dirty = visibleRegion;
683edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // as well, as the old visible region
684edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dirty.orSelf(layer->visibleRegionScreen);
685edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->contentDirty = false;
686edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
687a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian            /* compute the exposed region:
688ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   the exposed region consists of two components:
689ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   1) what's VISIBLE now and was COVERED before
690ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   2) what's EXPOSED now less what was EXPOSED before
691ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
692ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * note that (1) is conservative, we start with the whole
693ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * visible region but only keep what used to be covered by
694ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * something -- which mean it may have been exposed.
695ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
696ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * (2) handles areas that were not covered by anything but got
697ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * exposed because of a resize.
698a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian             */
699ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region newExposed = visibleRegion - coveredRegion;
700ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldVisibleRegion = layer->visibleRegionScreen;
701ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldCoveredRegion = layer->coveredRegionScreen;
702ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldExposed = oldVisibleRegion - oldCoveredRegion;
703ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed);
704edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
705edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirty.subtractSelf(aboveOpaqueLayers);
706edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
707edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // accumulate to the screen dirty region
708edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirtyRegion.orSelf(dirty);
709edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
710ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveOpaqueLayers for next (lower) layer
711edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        aboveOpaqueLayers.orSelf(opaqueRegion);
7128b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
713edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // Store the visible region is screen space
714edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setVisibleRegion(visibleRegion);
715edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setCoveredRegion(coveredRegion);
716edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
717970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian        // If a secure layer is partially visible, lock-down the screen!
718edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (layer->isSecure() && !visibleRegion.isEmpty()) {
719edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            secureFrameBuffer = true;
720edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
721edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
722edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
723970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian    // invalidate the areas where a layer was removed
724970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian    dirtyRegion.orSelf(mDirtyRegionRemovedLayer);
725970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian    mDirtyRegionRemovedLayer.clear();
726970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian
727edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mSecureFrameBuffer = secureFrameBuffer;
728edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    opaqueRegion = aboveOpaqueLayers;
729edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
730edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
731edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
732edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::commitTransaction()
733edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
7342f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall    if (!mLayersPendingRemoval.isEmpty()) {
7352f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall        // Notify removed layers now that they can't be drawn from
7362f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall        for (size_t i = 0; i < mLayersPendingRemoval.size(); i++) {
7372f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall            mLayersPendingRemoval[i]->onRemoved();
7382f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall        }
7392f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall        mLayersPendingRemoval.clear();
7402f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall    }
7412f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall
742edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDrawingState = mCurrentState;
74328378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    mTransationPending = false;
744cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mTransactionCV.broadcast();
745edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
746edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
747edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handlePageFlip()
748edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
7491c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
75099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    const DisplayHardware& hw = graphicPlane(0).displayHardware();
75199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    const Region screenRegion(hw.bounds());
75299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
7531bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian    const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
75499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    const bool visibleRegions = lockPageFlip(currentLayers);
755edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
75699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        if (visibleRegions || mVisibleRegionsDirty) {
757edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            Region opaqueRegion;
758edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            computeVisibleRegions(currentLayers, mDirtyRegion, opaqueRegion);
7594da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
7604da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            /*
7614da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian             *  rebuild the visible layer list
7624da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian             */
7631bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian            const size_t count = currentLayers.size();
7644da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            mVisibleLayersSortedByZ.clear();
7654da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            mVisibleLayersSortedByZ.setCapacity(count);
7664da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            for (size_t i=0 ; i<count ; i++) {
7674da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian                if (!currentLayers[i]->visibleRegionScreen.isEmpty())
7684da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian                    mVisibleLayersSortedByZ.add(currentLayers[i]);
7694da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            }
7704da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
771edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mWormholeRegion = screenRegion.subtract(opaqueRegion);
772edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = false;
773ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian            invalidateHwcGeometry();
774edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
775edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
776edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    unlockPageFlip(currentLayers);
7770dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian
7780dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    mDirtyRegion.orSelf(getAndClearInvalidateRegion());
779edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDirtyRegion.andSelf(screenRegion);
780edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
781edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
782ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopianvoid SurfaceFlinger::invalidateHwcGeometry()
783ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian{
784ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian    mHwWorkListDirty = true;
785ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian}
786ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian
787edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool SurfaceFlinger::lockPageFlip(const LayerVector& currentLayers)
788edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
789edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    bool recomputeVisibleRegions = false;
790edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t count = currentLayers.size();
791076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBase> const* layers = currentLayers.array();
792edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (size_t i=0 ; i<count ; i++) {
793b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
794edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->lockPageFlip(recomputeVisibleRegions);
795edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
796edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return recomputeVisibleRegions;
797edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
798edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
799edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::unlockPageFlip(const LayerVector& currentLayers)
800edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
801edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(graphicPlane(0));
802edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Transform& planeTransform(plane.transform());
80399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    const size_t count = currentLayers.size();
804076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBase> const* layers = currentLayers.array();
805edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (size_t i=0 ; i<count ; i++) {
806b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
807edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->unlockPageFlip(planeTransform, mDirtyRegion);
808edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
809edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
810edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
81199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::handleRefresh()
81299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
81399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    bool needInvalidate = false;
81499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
81599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    const size_t count = currentLayers.size();
81699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
81799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
81899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        if (layer->onPreComposition()) {
81999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            needInvalidate = true;
82099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        }
82199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    }
82299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    if (needInvalidate) {
82399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        signalLayerUpdate();
82499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    }
82599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
82699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
82799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
828a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopianvoid SurfaceFlinger::handleWorkList()
829a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian{
830a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    mHwWorkListDirty = false;
831a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    HWComposer& hwc(graphicPlane(0).displayHardware().getHwComposer());
832a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    if (hwc.initCheck() == NO_ERROR) {
833a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        const Vector< sp<LayerBase> >& currentLayers(mVisibleLayersSortedByZ);
834a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        const size_t count = currentLayers.size();
835a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        hwc.createWorkList(count);
83645721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        hwc_layer_t* const cur(hwc.getLayers());
83745721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        for (size_t i=0 ; cur && i<count ; i++) {
83845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            currentLayers[i]->setGeometry(&cur[i]);
83953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian            if (mDebugDisableHWC || mDebugRegion) {
84073d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian                cur[i].compositionType = HWC_FRAMEBUFFER;
84173d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian                cur[i].flags |= HWC_SKIP_LAYER;
84273d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian            }
843a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        }
844a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
845a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian}
846b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian
847edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleRepaint()
848edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
849841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
850841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
851b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // compute the invalid region
8520656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian    mSwapRegion.orSelf(mDirtyRegion);
853edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
85499ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten    if (CC_UNLIKELY(mDebugRegion)) {
855edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        debugFlashRegions();
856edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
857edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
858b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // set the frame buffer
859b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
860b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    glMatrixMode(GL_MODELVIEW);
861b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    glLoadIdentity();
862edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
863edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t flags = hw.getFlags();
8648b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber    if ((flags & DisplayHardware::SWAP_RECTANGLE) ||
8658b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber        (flags & DisplayHardware::BUFFER_PRESERVED))
866df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian    {
86729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // we can redraw only what's dirty, but since SWAP_RECTANGLE only
86829d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // takes a rectangle, we must make sure to update that whole
86929d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // rectangle in that case
87029d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        if (flags & DisplayHardware::SWAP_RECTANGLE) {
871b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            // TODO: we really should be able to pass a region to
87229d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // SWAP_RECTANGLE so that we don't have to redraw all this.
8730656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian            mDirtyRegion.set(mSwapRegion.bounds());
87429d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        } else {
87529d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // in the BUFFER_PRESERVED case, obviously, we can update only
87629d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // what's needed and nothing more.
87729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // NOTE: this is NOT a common case, as preserving the backbuffer
87829d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // is costly and usually involves copying the whole update back.
87929d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        }
880edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
88195a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian        if (flags & DisplayHardware::PARTIAL_UPDATES) {
88229d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // We need to redraw the rectangle that will be updated
883df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian            // (pushed to the framebuffer).
88495a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian            // This is needed because PARTIAL_UPDATES only takes one
88529d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // rectangle instead of a region (see DisplayHardware::flip())
8860656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian            mDirtyRegion.set(mSwapRegion.bounds());
887edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
88829d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // we need to redraw everything (the whole screen)
889edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mDirtyRegion.set(hw.bounds());
8900656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian            mSwapRegion = mDirtyRegion;
891edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
892edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
893edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
8949c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    setupHardwareComposer(mDirtyRegion);
895edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    composeSurfaces(mDirtyRegion);
896edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
8979c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    // update the swap region and clear the dirty region
8989c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    mSwapRegion.orSelf(mDirtyRegion);
899edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDirtyRegion.clear();
900edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
901edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
9029c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopianvoid SurfaceFlinger::setupHardwareComposer(Region& dirtyInOut)
903edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
904f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
905f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    HWComposer& hwc(hw.getHwComposer());
906f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    hwc_layer_t* const cur(hwc.getLayers());
907f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    if (!cur) {
9089c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        return;
909edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
910a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
9114da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian    const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
91245721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    size_t count = layers.size();
913a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
914e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block    ALOGE_IF(hwc.getNumLayers() != count,
91545721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            "HAL number of layers (%d) doesn't match surfaceflinger (%d)",
91645721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            hwc.getNumLayers(), count);
917a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
91845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    // just to be extra-safe, use the smallest count
91924925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling    if (hwc.initCheck() == NO_ERROR) {
92024925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling        count = count < hwc.getNumLayers() ? count : hwc.getNumLayers();
92124925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling    }
922a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
92345721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    /*
92445721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     *  update the per-frame h/w composer data for each layer
92545721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     *  and build the transparent region of the FB
92645721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     */
927f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
928f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
929f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        layer->setPerFrameData(&cur[i]);
930f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    }
9319c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    const size_t fbLayerCount = hwc.getLayerCount(HWC_FRAMEBUFFER);
932f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    status_t err = hwc.prepare();
933e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block    ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
934f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian
935f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    if (err == NO_ERROR) {
9369c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // what's happening here is tricky.
9379c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // we want to clear all the layers with the CLEAR_FB flags
9389c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // that are opaque.
9399c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // however, since some GPU are efficient at preserving
9409c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // the backbuffer, we want to take advantage of that so we do the
9419c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // clear only in the dirty region (other areas will be preserved
9429c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // on those GPUs).
9439c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        //   NOTE: on non backbuffer preserving GPU, the dirty region
9449c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        //   has already been expanded as needed, so the code is correct
9459c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        //   there too.
9469c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        //
9479c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // However, the content of the framebuffer cannot be trusted when
9489c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // we switch to/from FB/OVERLAY, in which case we need to
9499c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // expand the dirty region to those areas too.
9509c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        //
9519c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // Note also that there is a special case when switching from
9529c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // "no layers in FB" to "some layers in FB", where we need to redraw
9539c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // the entire FB, since some areas might contain uninitialized
9549c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // data.
9559c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        //
9569c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // Also we want to make sure to not clear areas that belong to
9573a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian        // layers above that won't redraw (we would just be erasing them),
9589c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        // that is, we can't erase anything outside the dirty region.
959a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
9609c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        Region transparent;
961f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian
9629c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        if (!fbLayerCount && hwc.getLayerCount(HWC_FRAMEBUFFER)) {
9639c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian            transparent.set(hw.getBounds());
9649c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian            dirtyInOut = transparent;
9659c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        } else {
9669c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian            for (size_t i=0 ; i<count ; i++) {
9679c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                const sp<LayerBase>& layer(layers[i]);
9689c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                if ((cur[i].hints & HWC_HINT_CLEAR_FB) && layer->isOpaque()) {
9699c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                    transparent.orSelf(layer->visibleRegionScreen);
9709c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                }
9719c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                bool isOverlay = (cur[i].compositionType != HWC_FRAMEBUFFER);
9729c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                if (isOverlay != layer->isOverlay()) {
9739c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                    // we transitioned to/from overlay, so add this layer
9749c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                    // to the dirty region so the framebuffer can be either
9759c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                    // cleared or redrawn.
9769c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                    dirtyInOut.orSelf(layer->visibleRegionScreen);
9779c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                }
9789c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian                layer->setOverlay(isOverlay);
979f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian            }
9809c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian            // don't erase stuff outside the dirty region
9819c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian            transparent.andSelf(dirtyInOut);
982f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        }
983f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian
984f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        /*
985f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian         *  clear the area of the FB that need to be transparent
986f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian         */
987f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        if (!transparent.isEmpty()) {
988f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian            glClearColor(0,0,0,0);
989f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian            Region::const_iterator it = transparent.begin();
990f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian            Region::const_iterator const end = transparent.end();
991f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian            const int32_t height = hw.getHeight();
992f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian            while (it != end) {
993f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian                const Rect& r(*it++);
994f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian                const GLint sy = height - (r.top + r.height());
995f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian                glScissor(r.left, sy, r.width(), r.height());
996f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian                glClear(GL_COLOR_BUFFER_BIT);
997f20a32415d055336bc6016fa2de36d126db32746Mathias Agopian            }
998a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        }
999a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
1000f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian}
1001f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian
1002f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopianvoid SurfaceFlinger::composeSurfaces(const Region& dirty)
1003f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian{
1004cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
1005cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian    HWComposer& hwc(hw.getHwComposer());
1006cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian
1007cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian    const size_t fbLayerCount = hwc.getLayerCount(HWC_FRAMEBUFFER);
100899ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten    if (CC_UNLIKELY(fbLayerCount && !mWormholeRegion.isEmpty())) {
1009f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        // should never happen unless the window manager has a bug
1010f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        // draw something...
1011f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        drawWormhole();
1012f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    }
101345721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian
1014fbc7922ec87298601ba6a3be1bd9f83ffaf9a233Mathias Agopian    // FIXME: workaroud for b/6020860
1015fbc7922ec87298601ba6a3be1bd9f83ffaf9a233Mathias Agopian    glEnable(GL_SCISSOR_TEST);
1016fbc7922ec87298601ba6a3be1bd9f83ffaf9a233Mathias Agopian    glScissor(0,0,0,0);
1017fbc7922ec87298601ba6a3be1bd9f83ffaf9a233Mathias Agopian    glClear(GL_COLOR_BUFFER_BIT);
1018fbc7922ec87298601ba6a3be1bd9f83ffaf9a233Mathias Agopian    // end-workaround
1019fbc7922ec87298601ba6a3be1bd9f83ffaf9a233Mathias Agopian
102045721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    /*
102145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     * and then, render the layers targeted at the framebuffer
102245721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     */
1023cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian    hwc_layer_t* const cur(hwc.getLayers());
1024f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
1025f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    size_t count = layers.size();
102645721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
10279c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        if (cur && (cur[i].compositionType != HWC_FRAMEBUFFER)) {
1028f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian            continue;
102945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        }
103045721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
103145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        const Region clip(dirty.intersect(layer->visibleRegionScreen));
103245721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        if (!clip.isEmpty()) {
103345721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            layer->draw(clip);
103445721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        }
103545721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    }
1036edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1037edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1038edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::debugFlashRegions()
1039edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
10400a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
10410a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    const uint32_t flags = hw.getFlags();
104253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian    const int32_t height = hw.getHeight();
10430656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian    if (mSwapRegion.isEmpty()) {
104453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian        return;
104553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian    }
10460a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
10470a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    if (!((flags & DisplayHardware::SWAP_RECTANGLE) ||
10480a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian            (flags & DisplayHardware::BUFFER_PRESERVED))) {
10490a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        const Region repaint((flags & DisplayHardware::PARTIAL_UPDATES) ?
10500a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian                mDirtyRegion.bounds() : hw.bounds());
10510a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        composeSurfaces(repaint);
10520a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    }
10530a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
1054c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_EXTERNAL_OES);
1055c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_2D);
1056edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_BLEND);
1057edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_SCISSOR_TEST);
1058edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
10590926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    static int toggle = 0;
10600926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    toggle = 1 - toggle;
10610926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    if (toggle) {
10620a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        glColor4f(1, 0, 1, 1);
10630926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    } else {
10640a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        glColor4f(1, 1, 0, 1);
10650926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    }
1066edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
106720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    Region::const_iterator it = mDirtyRegion.begin();
106820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    Region::const_iterator const end = mDirtyRegion.end();
106920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    while (it != end) {
107020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        const Rect& r = *it++;
1071edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLfloat vertices[][2] = {
107253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.left,  height - r.top },
107353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.left,  height - r.bottom },
107453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.right, height - r.bottom },
107553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.right, height - r.top }
1076edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        };
1077edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glVertexPointer(2, GL_FLOAT, 0, vertices);
1078edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1079edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
10800a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
10810656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian    hw.flip(mSwapRegion);
1082edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1083edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mDebugRegion > 1)
10840a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        usleep(mDebugRegion * 1000);
1085edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1086edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glEnable(GL_SCISSOR_TEST);
1087edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1088edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1089edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::drawWormhole() const
1090edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1091edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Region region(mWormholeRegion.intersect(mDirtyRegion));
1092edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (region.isEmpty())
1093edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1094edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1095edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw(graphicPlane(0).displayHardware());
1096edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int32_t width = hw.getWidth();
1097edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int32_t height = hw.getHeight();
1098edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
109999ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten    if (CC_LIKELY(!mDebugBackground)) {
11000a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        glClearColor(0,0,0,0);
110120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        Region::const_iterator it = region.begin();
110220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        Region::const_iterator const end = region.end();
110320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        while (it != end) {
110420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            const Rect& r = *it++;
1105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const GLint sy = height - (r.top + r.height());
1106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glScissor(r.left, sy, r.width(), r.height());
1107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glClear(GL_COLOR_BUFFER_BIT);
1108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
1110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GLshort vertices[][2] = { { 0, 0 }, { width, 0 },
1111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                { width, height }, { 0, height }  };
1112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GLshort tcoords[][2] = { { 0, 0 }, { 1, 0 },  { 1, 1 }, { 0, 1 } };
1113c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian
1114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glVertexPointer(2, GL_SHORT, 0, vertices);
1115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glTexCoordPointer(2, GL_SHORT, 0, tcoords);
1116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
1117c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian
1118c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian        glDisable(GL_TEXTURE_EXTERNAL_OES);
1119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glEnable(GL_TEXTURE_2D);
1120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glBindTexture(GL_TEXTURE_2D, mWormholeTexName);
1121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glMatrixMode(GL_TEXTURE);
1123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glLoadIdentity();
1124c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian
1125c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian        glDisable(GL_BLEND);
1126c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian
1127edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glScalef(width*(1.0f/32.0f), height*(1.0f/32.0f), 1);
112820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        Region::const_iterator it = region.begin();
112920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        Region::const_iterator const end = region.end();
113020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        while (it != end) {
113120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            const Rect& r = *it++;
1132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const GLint sy = height - (r.top + r.height());
1133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glScissor(r.left, sy, r.width(), r.height());
1134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1137a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        glDisable(GL_TEXTURE_2D);
1138ebeb7095961e09f5cff0c7cf2c04fa4770b2e033Mathias Agopian        glLoadIdentity();
1139ebeb7095961e09f5cff0c7cf2c04fa4770b2e033Mathias Agopian        glMatrixMode(GL_MODELVIEW);
1140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1141edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1142edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1143076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::addLayer(const sp<LayerBase>& layer)
1144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1145edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
1146edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    addLayer_l(layer);
1147edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
1148edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1149edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1150edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1151076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::addLayer_l(const sp<LayerBase>& layer)
1152edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1153f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian    ssize_t i = mCurrentState.layersSortedByZ.add(layer);
11541b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    return (i < 0) ? status_t(i) : status_t(NO_ERROR);
11551b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian}
11561b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
115796f0819f81293076e652792794a961543e6750d7Mathias Agopianssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
115896f0819f81293076e652792794a961543e6750d7Mathias Agopian        const sp<LayerBaseClient>& lbc)
11591b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
116096f0819f81293076e652792794a961543e6750d7Mathias Agopian    // attach this layer to the client
11614f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    size_t name = client->attachLayer(lbc);
11624f113740180b6512b43723c4728f262882dc9b45Mathias Agopian
11634f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    Mutex::Autolock _l(mStateLock);
116496f0819f81293076e652792794a961543e6750d7Mathias Agopian
116596f0819f81293076e652792794a961543e6750d7Mathias Agopian    // add this layer to the current state list
116696f0819f81293076e652792794a961543e6750d7Mathias Agopian    addLayer_l(lbc);
116796f0819f81293076e652792794a961543e6750d7Mathias Agopian
11684f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    return ssize_t(name);
116996f0819f81293076e652792794a961543e6750d7Mathias Agopian}
117096f0819f81293076e652792794a961543e6750d7Mathias Agopian
117196f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer)
117296f0819f81293076e652792794a961543e6750d7Mathias Agopian{
117396f0819f81293076e652792794a961543e6750d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
117496f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = purgatorizeLayer_l(layer);
117596f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR)
117696f0819f81293076e652792794a961543e6750d7Mathias Agopian        setTransactionFlags(eTransactionNeeded);
117796f0819f81293076e652792794a961543e6750d7Mathias Agopian    return err;
1178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1180076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase)
1181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1182b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<LayerBaseClient> lbc(layerBase->getLayerBaseClient());
1183b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (lbc != 0) {
11840d1561275e80073807ac04728951782d943f8882Mathias Agopian        mLayerMap.removeItem( lbc->getSurfaceBinder() );
1185b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    }
1186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase);
1187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (index >= 0) {
1188076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved = true;
1189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
1190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
11913d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    return status_t(index);
1192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
11949a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase)
11959a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
119676cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    // First add the layer to the purgatory list, which makes sure it won't
119776cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    // go away, then remove it from the main list (through a transaction).
11989a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    ssize_t err = removeLayer_l(layerBase);
119976cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    if (err >= 0) {
120076cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian        mLayerPurgatory.add(layerBase);
120176cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    }
12028c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian
12032f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall    mLayersPendingRemoval.push(layerBase);
12040b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian
12053d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // it's possible that we don't find a layer, because it might
12063d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // have been destroyed already -- this is not technically an error
120796f0819f81293076e652792794a961543e6750d7Mathias Agopian    // from the user because there is a race between Client::destroySurface(),
120896f0819f81293076e652792794a961543e6750d7Mathias Agopian    // ~Client() and ~ISurface().
12099a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err;
12109a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
12119a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
121296f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::invalidateLayerVisibility(const sp<LayerBase>& layer)
1213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
121496f0819f81293076e652792794a961543e6750d7Mathias Agopian    layer->forceVisibilityTransaction();
121596f0819f81293076e652792794a961543e6750d7Mathias Agopian    setTransactionFlags(eTraversalNeeded);
121696f0819f81293076e652792794a961543e6750d7Mathias Agopian    return NO_ERROR;
1217edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1219dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopianuint32_t SurfaceFlinger::peekTransactionFlags(uint32_t flags)
1220dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian{
1221dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian    return android_atomic_release_load(&mTransactionFlags);
1222dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian}
1223dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian
1224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags)
1225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return android_atomic_and(~flags, &mTransactionFlags) & flags;
1227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1229bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags)
1230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t old = android_atomic_or(flags, &mTransactionFlags);
1232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((old & flags)==0) { // wake the server up
123399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        signalTransaction();
1234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return old;
1236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1239b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennisvoid SurfaceFlinger::setTransactionState(const Vector<ComposerState>& state,
124028378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        int orientation, uint32_t flags) {
1241698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
1242cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
124328378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    uint32_t transactionFlags = 0;
1244b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis    if (mCurrentState.orientation != orientation) {
1245b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis        if (uint32_t(orientation)<=eOrientation270 || orientation==42) {
1246b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis            mCurrentState.orientation = orientation;
124728378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis            transactionFlags |= eTransactionNeeded;
1248b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis        } else if (orientation != eOrientationUnchanged) {
124932397c1cd3327905173b36baa6fd1c579bc328ffSteve Block            ALOGW("setTransactionState: ignoring unrecognized orientation: %d",
1250b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis                    orientation);
1251b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis        }
1252b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis    }
1253b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis
1254698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    const size_t count = state.size();
1255698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
1256698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const ComposerState& s(state[i]);
1257698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        sp<Client> client( static_cast<Client *>(s.client.get()) );
125828378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        transactionFlags |= setClientStateLocked(client, s.state);
1259698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    }
1260386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian
126128378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    if (transactionFlags) {
1262386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // this triggers the transaction
126328378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        setTransactionFlags(transactionFlags);
1264698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian
1265386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // if this is a synchronous transaction, wait for it to take effect
1266386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // before returning.
1267386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        if (flags & eSynchronous) {
1268386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            mTransationPending = true;
1269386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        }
1270386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        while (mTransationPending) {
1271386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
1272386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            if (CC_UNLIKELY(err != NO_ERROR)) {
1273386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                // just in case something goes wrong in SF, return to the
1274386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                // called after a few seconds.
127532397c1cd3327905173b36baa6fd1c579bc328ffSteve Block                ALOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!");
1276386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                mTransationPending = false;
1277386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                break;
1278386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            }
1279cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        }
1280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
12830ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopiansp<ISurface> SurfaceFlinger::createSurface(
12840ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        ISurfaceComposerClient::surface_data_t* params,
12850ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const String8& name,
12860ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const sp<Client>& client,
1287edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        DisplayID d, uint32_t w, uint32_t h, PixelFormat format,
1288edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t flags)
1289edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1290076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBaseClient> layer;
1291a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    sp<ISurface> surfaceHandle;
12926e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian
12936e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    if (int32_t(w|h) < 0) {
1294e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE("createSurface() failed, w or h is negative (w=%d, h=%d)",
12956e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian                int(w), int(h));
12966e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian        return surfaceHandle;
12976e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    }
12988b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
1299ff615cc7a1cceedd705b0623b058c54669b29596Mathias Agopian    //ALOGD("createSurface for (%d x %d), name=%s", w, h, name.string());
1300b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<Layer> normalLayer;
1301edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (flags & eFXSurfaceMask) {
1302edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceNormal:
1303a5529c8778c2f407f482fc12165aeb76c0f505c2Mathias Agopian            normalLayer = createNormalSurface(client, d, w, h, flags, format);
1304a5529c8778c2f407f482fc12165aeb76c0f505c2Mathias Agopian            layer = normalLayer;
1305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
1306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceBlur:
13071293a8eb567fd63c072a6970fa9dcf37d076059fMathias Agopian            // for now we treat Blur as Dim, until we can implement it
13081293a8eb567fd63c072a6970fa9dcf37d076059fMathias Agopian            // efficiently.
1309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceDim:
131096f0819f81293076e652792794a961543e6750d7Mathias Agopian            layer = createDimSurface(client, d, w, h, flags);
1311edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
1312118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        case eFXSurfaceScreenshot:
1313118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian            layer = createScreenshotSurface(client, d, w, h, flags);
1314118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian            break;
1315edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1317076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (layer != 0) {
131896f0819f81293076e652792794a961543e6750d7Mathias Agopian        layer->initStates(w, h, flags);
1319285dbde2e0cd0057be070ded3be8f5f453147edcMathias Agopian        layer->setName(name);
132096f0819f81293076e652792794a961543e6750d7Mathias Agopian        ssize_t token = addClientLayer(client, layer);
1321b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        surfaceHandle = layer->getSurface();
13238b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber        if (surfaceHandle != 0) {
132496f0819f81293076e652792794a961543e6750d7Mathias Agopian            params->token = token;
1325a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            params->identity = layer->getIdentity();
1326b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            if (normalLayer != 0) {
1327b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian                Mutex::Autolock _l(mStateLock);
1328a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                mLayerMap.add(layer->getSurfaceBinder(), normalLayer);
1329b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            }
13301c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        }
1331b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
133296f0819f81293076e652792794a961543e6750d7Mathias Agopian        setTransactionFlags(eTransactionNeeded);
1333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1334edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1335edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return surfaceHandle;
1336edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1337edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1338b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<Layer> SurfaceFlinger::createNormalSurface(
1339f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        const sp<Client>& client, DisplayID display,
134096f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags,
13411c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        PixelFormat& format)
1342edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1343edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize the surfaces
1344edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (format) { // TODO: take h/w into account
1345edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSPARENT:
1346edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSLUCENT:
1347edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        format = PIXEL_FORMAT_RGBA_8888;
1348edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1349edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_OPAQUE:
1350a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888
1351a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian        format = PIXEL_FORMAT_RGB_565;
1352a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#else
13538f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian        format = PIXEL_FORMAT_RGBX_8888;
1354a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif
1355edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1356edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1357edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1358a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888
1359a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian    if (format == PIXEL_FORMAT_RGBX_8888)
1360a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian        format = PIXEL_FORMAT_RGBA_8888;
1361a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif
1362a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian
136396f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<Layer> layer = new Layer(this, display, client);
1364f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian    status_t err = layer->setBuffers(w, h, format, flags);
136599ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten    if (CC_LIKELY(err != NO_ERROR)) {
1366e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE("createNormalSurfaceLocked() failed (%s)", strerror(-err));
1367076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        layer.clear();
1368edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1369edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1370edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1371edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1372b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<LayerDim> SurfaceFlinger::createDimSurface(
1373f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        const sp<Client>& client, DisplayID display,
137496f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags)
1375edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
137696f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<LayerDim> layer = new LayerDim(this, display, client);
1377118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    return layer;
1378118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
1379118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
1380118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopiansp<LayerScreenshot> SurfaceFlinger::createScreenshotSurface(
1381118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        const sp<Client>& client, DisplayID display,
1382118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags)
1383118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{
1384118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    sp<LayerScreenshot> layer = new LayerScreenshot(this, display, client);
1385edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1386edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1387edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
138896f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeSurface(const sp<Client>& client, SurfaceID sid)
13899a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
13909a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    /*
13919a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     * called by the window manager, when a surface should be marked for
13929a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     * destruction.
13938b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber     *
13940aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * The surface is removed from the current and drawing lists, but placed
13950aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * in the purgatory queue, so it's not destroyed right-away (we need
13960aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * to wait for all client's references to go away first).
13979a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     */
13989a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
139948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    status_t err = NAME_NOT_FOUND;
14000aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian    Mutex::Autolock _l(mStateLock);
140196f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<LayerBaseClient> layer = client->getLayerUser(sid);
140248d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    if (layer != 0) {
140348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        err = purgatorizeLayer_l(layer);
140448d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        if (err == NO_ERROR) {
140548d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian            setTransactionFlags(eTransactionNeeded);
140648d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        }
14079a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    }
14089a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return err;
14099a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
14109a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
1411ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopianstatus_t SurfaceFlinger::destroySurface(const wp<LayerBaseClient>& layer)
1412edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1413759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian    // called by ~ISurface() when all references are gone
1414ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    status_t err = NO_ERROR;
1415ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    sp<LayerBaseClient> l(layer.promote());
1416ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    if (l != NULL) {
1417ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        Mutex::Autolock _l(mStateLock);
1418ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        err = removeLayer_l(l);
1419ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        if (err == NAME_NOT_FOUND) {
1420ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // The surface wasn't in the current list, which means it was
1421ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // removed already, which means it is in the purgatory,
1422ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // and need to be removed from there.
1423ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            ssize_t idx = mLayerPurgatory.remove(l);
1424e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block            ALOGE_IF(idx < 0,
1425ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian                    "layer=%p is not in the purgatory list", l.get());
1426f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        }
1427e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE_IF(err<0 && err != NAME_NOT_FOUND,
1428ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian                "error removing layer=%p (%s)", l.get(), strerror(-err));
1429ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    }
1430ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    return err;
1431edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1432edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1433698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopianuint32_t SurfaceFlinger::setClientStateLocked(
143496f0819f81293076e652792794a961543e6750d7Mathias Agopian        const sp<Client>& client,
1435698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const layer_state_t& s)
1436edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1437edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t flags = 0;
1438698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    sp<LayerBaseClient> layer(client->getLayerUser(s.surface));
1439698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    if (layer != 0) {
1440698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const uint32_t what = s.what;
1441698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & ePositionChanged) {
1442698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setPosition(s.x, s.y))
1443698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1444698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1445698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eLayerChanged) {
1446698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
1447698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setLayer(s.z)) {
1448698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                mCurrentState.layersSortedByZ.removeAt(idx);
1449698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                mCurrentState.layersSortedByZ.add(layer);
1450698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                // we need traversal (state changed)
1451698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                // AND transaction (list changed)
1452698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTransactionNeeded|eTraversalNeeded;
1453edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1454698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1455698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eSizeChanged) {
1456698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setSize(s.w, s.h)) {
1457698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1458edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1459edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1460698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eAlphaChanged) {
1461698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f)))
1462698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1463698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1464698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eMatrixChanged) {
1465698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setMatrix(s.matrix))
1466698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1467698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1468698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eTransparentRegionChanged) {
1469698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setTransparentRegionHint(s.transparentRegion))
1470698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1471698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1472698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eVisibilityChanged) {
1473698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setFlags(s.flags, s.mask))
1474698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1475698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1476edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1477698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    return flags;
1478edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1479edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1480edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::screenReleased(int dpy)
1481edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1482edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // this may be called by a signal handler, we can't do too much in here
1483edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    android_atomic_or(eConsoleReleased, &mConsoleSignals);
148499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    signalTransaction();
1485edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1486edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1487edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::screenAcquired(int dpy)
1488edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1489edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // this may be called by a signal handler, we can't do too much in here
1490edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    android_atomic_or(eConsoleAcquired, &mConsoleSignals);
149199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    signalTransaction();
1492edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1493edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1494edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
1495edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
14961d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling    const size_t SIZE = 4096;
1497edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char buffer[SIZE];
1498edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    String8 result;
149999b49840d309727678b77403d6cc9f920111623fMathias Agopian
150099b49840d309727678b77403d6cc9f920111623fMathias Agopian    if (!PermissionCache::checkCallingPermission(sDump)) {
1501edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        snprintf(buffer, SIZE, "Permission Denial: "
1502edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                "can't dump SurfaceFlinger from pid=%d, uid=%d\n",
1503edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                IPCThreadState::self()->getCallingPid(),
1504edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                IPCThreadState::self()->getCallingUid());
1505edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        result.append(buffer);
1506edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
15079795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // Try to get the main lock, but don't insist if we can't
15089795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // (this would indicate SF is stuck, but we want to be able to
15099795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // print something in dumpsys).
15109795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        int retry = 3;
15119795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        while (mStateLock.tryLock()<0 && --retry>=0) {
15129795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            usleep(1000000);
15139795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
15149795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const bool locked(retry >= 0);
15159795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (!locked) {
15168b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber            snprintf(buffer, SIZE,
15179795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "SurfaceFlinger appears to be unresponsive, "
15189795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "dumping anyways (no locks held)\n");
15199795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            result.append(buffer);
15209795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
15219795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
152282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        bool dumpAll = true;
152382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        size_t index = 0;
152425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        size_t numArgs = args.size();
152525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        if (numArgs) {
152625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
152725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--list"))) {
152825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                index++;
152925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                listLayersLocked(args, index, result, buffer, SIZE);
153035aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
153125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            }
153225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
153325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
153425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--latency"))) {
153582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                index++;
153682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                dumpStatsLocked(args, index, result, buffer, SIZE);
153735aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
153882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            }
153925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
154025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
154125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--latency-clear"))) {
154225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                index++;
154325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                clearStatsLocked(args, index, result, buffer, SIZE);
154435aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
154525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            }
1546edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
15471b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
154882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (dumpAll) {
154982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            dumpAllLocked(result, buffer, SIZE);
155082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
155148b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
155282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (locked) {
155382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mStateLock.unlock();
155448b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        }
155582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
155682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    write(fd, result.string(), result.size());
155782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    return NO_ERROR;
155882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
155948b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
156025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::listLayersLocked(const Vector<String16>& args, size_t& index,
156125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        String8& result, char* buffer, size_t SIZE) const
156225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
156325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
156425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const size_t count = currentLayers.size();
156525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
156625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
156725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        snprintf(buffer, SIZE, "%s\n", layer->getName().string());
156825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        result.append(buffer);
156925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
157025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
157125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
157282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index,
157382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        String8& result, char* buffer, size_t SIZE) const
157482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
157582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    String8 name;
157682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    if (index < args.size()) {
157782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        name = String8(args[index]);
157882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        index++;
157982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
158048b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
158182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
158282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const size_t count = currentLayers.size();
158382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    for (size_t i=0 ; i<count ; i++) {
158482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
158582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (name.isEmpty()) {
158682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            snprintf(buffer, SIZE, "%s\n", layer->getName().string());
158782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            result.append(buffer);
158882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
158982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (name.isEmpty() || (name == layer->getName())) {
159082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            layer->dumpStats(result, buffer, SIZE);
159182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
159282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
159382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
1594ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian
159525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& index,
159625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        String8& result, char* buffer, size_t SIZE) const
159725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
159825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    String8 name;
159925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    if (index < args.size()) {
160025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        name = String8(args[index]);
160125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        index++;
160225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
160325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
160425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
160525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const size_t count = currentLayers.size();
160625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
160725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
160825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        if (name.isEmpty() || (name == layer->getName())) {
160925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            layer->clearStats();
161025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        }
161125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
161225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
161325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
161482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpAllLocked(
161582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        String8& result, char* buffer, size_t SIZE) const
161682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
161782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    // figure out if we're stuck somewhere
161882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t now = systemTime();
161982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t inSwapBuffers(mDebugInSwapBuffers);
162082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t inTransaction(mDebugInTransaction);
162182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0;
162282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0;
1623bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
162482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
162582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump the visible layer list
162682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
162782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
162882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const size_t count = currentLayers.size();
162982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "Visible layers (count = %d)\n", count);
163082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
163182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    for (size_t i=0 ; i<count ; i++) {
163282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
163382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        layer->dump(result, buffer, SIZE);
163482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
1635bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
163682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
163782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump the layers in the purgatory
163882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
1639ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian
164082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const size_t purgatorySize = mLayerPurgatory.size();
164182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "Purgatory state (%d entries)\n", purgatorySize);
164282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
164382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    for (size_t i=0 ; i<purgatorySize ; i++) {
164482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
164582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        layer->shortDump(result, buffer, SIZE);
164682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
16471b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
164882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
164982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump SurfaceFlinger global state
165082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
16511b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
165282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "SurfaceFlinger global state:\n");
165382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
16541b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
165582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const GLExtensions& extensions(GLExtensions::getInstance());
165682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "GLES: %s, %s, %s\n",
165782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            extensions.getVendor(),
165882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            extensions.getRenderer(),
165982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            extensions.getVersion());
166082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
1661d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
166282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "EGL : %s\n",
166382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            eglQueryString(graphicPlane(0).getEGLDisplay(),
166482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                    EGL_VERSION_HW_ANDROID));
166582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
166673d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian
166782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "EXTS: %s\n", extensions.getExtension());
166882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
16699795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
167082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    mWormholeRegion.dump(result, "WormholeRegion");
167182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
167282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE,
167382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  orientation=%d, canDraw=%d\n",
167482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mCurrentState.orientation, hw.canDraw());
167582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
167682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE,
167782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  last eglSwapBuffers() time: %f us\n"
167882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  last transaction time     : %f us\n"
1679c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian            "  transaction-flags         : %08x\n"
168082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  refresh-rate              : %f fps\n"
168182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  x-dpi                     : %f\n"
168282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  y-dpi                     : %f\n",
168382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mLastSwapBufferTime/1000.0,
168482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mLastTransactionTime/1000.0,
1685c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian            mTransactionFlags,
168682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            hw.getRefreshRate(),
168782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            hw.getDpiX(),
168882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            hw.getDpiY());
168982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
169082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
169182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "  eglSwapBuffers time: %f us\n",
169282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            inSwapBuffersDuration/1000.0);
169382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
169482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
169582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "  transaction time: %f us\n",
169682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            inTransactionDuration/1000.0);
169782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
169882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
169982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
170082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * VSYNC state
170182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
170282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    mEventThread->dump(result, buffer, SIZE);
170382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
170482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
170582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump HWComposer state
170682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
170782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    HWComposer& hwc(hw.getHwComposer());
170882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "h/w composer state:\n");
170982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
171082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "  h/w composer %s and %s\n",
171182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            hwc.initCheck()==NO_ERROR ? "present" : "not present",
171282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                    (mDebugDisableHWC || mDebugRegion) ? "disabled" : "enabled");
171382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
171482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    hwc.dump(result, buffer, SIZE, mVisibleLayersSortedByZ);
171582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
171682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
171782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump gralloc state
171882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
171982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
172082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    alloc.dump(result);
172182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    hw.dump(result);
1722edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1723edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1724edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::onTransact(
1725edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
1726edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1727edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (code) {
1728edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case CREATE_CONNECTION:
1729698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        case SET_TRANSACTION_STATE:
1730edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case SET_ORIENTATION:
1731edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case BOOT_FINISHED:
173259119e658a12279e8fff508f8773843de2d90917Mathias Agopian        case TURN_ELECTRON_BEAM_OFF:
17339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        case TURN_ELECTRON_BEAM_ON:
1734edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        {
1735edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // codes that require permission check
1736edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            IPCThreadState* ipc = IPCThreadState::self();
1737edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int pid = ipc->getCallingPid();
1738a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian            const int uid = ipc->getCallingUid();
173999b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
174099b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) {
1741e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block                ALOGE("Permission Denial: "
1742375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                        "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
1743375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                return PERMISSION_DENIED;
1744edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
17451b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
17461b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
17471b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        case CAPTURE_SCREEN:
17481b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
17491b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            // codes that require permission check
17501b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
17511b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int pid = ipc->getCallingPid();
17521b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int uid = ipc->getCallingUid();
175399b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
175499b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) {
1755e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block                ALOGE("Permission Denial: "
17561b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                        "can't read framebuffer pid=%d, uid=%d", pid, uid);
17571b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                return PERMISSION_DENIED;
17581b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            }
17591b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
1760edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1761edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
17621b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
1763edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
1764edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
1765b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        CHECK_INTERFACE(ISurfaceComposer, data, reply);
176699ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten        if (CC_UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) {
1767375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
1768375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int pid = ipc->getCallingPid();
1769375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int uid = ipc->getCallingUid();
1770e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block            ALOGE("Permission Denial: "
1771375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                    "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
1772edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return PERMISSION_DENIED;
1773edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1774edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int n;
1775edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        switch (code) {
177601b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian            case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE
177735b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian            case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE
1778edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1779edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1002:  // SHOW_UPDATES
1780edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                n = data.readInt32();
1781edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDebugRegion = n ? n : (mDebugRegion ? 0 : 1);
178253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
178353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
1784edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1785edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1003:  // SHOW_BACKGROUND
1786edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                n = data.readInt32();
1787edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDebugBackground = n ? 1 : 0;
1788edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1789edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1004:{ // repaint everything
179053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
1791cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
1792cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            }
1793cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            case 1005:{ // force transaction
1794cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
1795cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
1796edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
17974d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            case 1006:{ // send empty update
17984d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian                signalRefresh();
17994d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian                return NO_ERROR;
18004d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            }
180153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian            case 1008:  // toggle use of hw composer
180253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                n = data.readInt32();
180353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                mDebugDisableHWC = n ? 1 : 0;
180453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
180553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
180653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                return NO_ERROR;
1807a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian            case 1009:  // toggle use of transform hint
1808a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                n = data.readInt32();
1809a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                mDebugDisableTransformHint = n ? 1 : 0;
1810a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                invalidateHwcGeometry();
1811a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                repaintEverything();
1812a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                return NO_ERROR;
1813edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1010:  // interrogate.
181401b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian                reply->writeInt32(0);
1815edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(0);
1816edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(mDebugRegion);
1817edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(mDebugBackground);
181812839bee29bdcc65731b4d42029cc59e2320c5c4Dianne Hackborn                reply->writeInt32(mDebugDisableHWC);
1819edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1820edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1013: {
1821edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                Mutex::Autolock _l(mStateLock);
1822edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                const DisplayHardware& hw(graphicPlane(0).displayHardware());
1823edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(hw.getPageFlipCount());
1824edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1825edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return NO_ERROR;
1826edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1827edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1828edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return err;
1829edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1830edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
183153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopianvoid SurfaceFlinger::repaintEverything() {
183253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
18330dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    const Rect bounds(hw.getBounds());
18340dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    setInvalidateRegion(Region(bounds));
183599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    signalTransaction();
183653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian}
183753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian
18380dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopianvoid SurfaceFlinger::setInvalidateRegion(const Region& reg) {
18390dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    Mutex::Autolock _l(mInvalidateLock);
18400dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    mInvalidateRegion = reg;
18410dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian}
18420dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian
18430dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias AgopianRegion SurfaceFlinger::getAndClearInvalidateRegion() {
18440dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    Mutex::Autolock _l(mInvalidateLock);
18450dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    Region reg(mInvalidateRegion);
18460dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    mInvalidateRegion.clear();
18470dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    return reg;
18480dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian}
18490dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian
185059119e658a12279e8fff508f8773843de2d90917Mathias Agopian// ---------------------------------------------------------------------------
185159119e658a12279e8fff508f8773843de2d90917Mathias Agopian
1852118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopianstatus_t SurfaceFlinger::renderScreenToTexture(DisplayID dpy,
1853118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        GLuint* textureName, GLfloat* uOut, GLfloat* vOut)
1854118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{
1855118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    Mutex::Autolock _l(mStateLock);
1856118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    return renderScreenToTextureLocked(dpy, textureName, uOut, vOut);
1857118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
1858118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
18599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::renderScreenToTextureLocked(DisplayID dpy,
18609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        GLuint* textureName, GLfloat* uOut, GLfloat* vOut)
186159119e658a12279e8fff508f8773843de2d90917Mathias Agopian{
186259119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
186359119e658a12279e8fff508f8773843de2d90917Mathias Agopian        return INVALID_OPERATION;
186459119e658a12279e8fff508f8773843de2d90917Mathias Agopian
186559119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // get screen geometry
186659119e658a12279e8fff508f8773843de2d90917Mathias Agopian    const DisplayHardware& hw(graphicPlane(dpy).displayHardware());
186759119e658a12279e8fff508f8773843de2d90917Mathias Agopian    const uint32_t hw_w = hw.getWidth();
186859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    const uint32_t hw_h = hw.getHeight();
186959119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLfloat u = 1;
187059119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLfloat v = 1;
187159119e658a12279e8fff508f8773843de2d90917Mathias Agopian
187259119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // make sure to clear all GL error flags
187359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    while ( glGetError() != GL_NO_ERROR ) ;
187459119e658a12279e8fff508f8773843de2d90917Mathias Agopian
187559119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // create a FBO
187659119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLuint name, tname;
187759119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glGenTextures(1, &tname);
187859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
18799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
18809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            hw_w, hw_h, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
188159119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (glGetError() != GL_NO_ERROR) {
1882015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian        while ( glGetError() != GL_NO_ERROR ) ;
188359119e658a12279e8fff508f8773843de2d90917Mathias Agopian        GLint tw = (2 << (31 - clz(hw_w)));
188459119e658a12279e8fff508f8773843de2d90917Mathias Agopian        GLint th = (2 << (31 - clz(hw_h)));
18859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
18869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian                tw, th, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
188759119e658a12279e8fff508f8773843de2d90917Mathias Agopian        u = GLfloat(hw_w) / tw;
188859119e658a12279e8fff508f8773843de2d90917Mathias Agopian        v = GLfloat(hw_h) / th;
188959119e658a12279e8fff508f8773843de2d90917Mathias Agopian    }
189059119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glGenFramebuffersOES(1, &name);
189159119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
18929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES,
18939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0);
189459119e658a12279e8fff508f8773843de2d90917Mathias Agopian
18959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // redraw the screen entirely...
1896c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_EXTERNAL_OES);
1897c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_2D);
189862f7114719d2009dca7dd120f0fe29a24bd77a40Mathias Agopian    glDisable(GL_SCISSOR_TEST);
18999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glClearColor(0,0,0,1);
19009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glClear(GL_COLOR_BUFFER_BIT);
190162f7114719d2009dca7dd120f0fe29a24bd77a40Mathias Agopian    glEnable(GL_SCISSOR_TEST);
1902a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glMatrixMode(GL_MODELVIEW);
1903a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glLoadIdentity();
19049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
19059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const size_t count = layers.size();
19069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (size_t i=0 ; i<count ; ++i) {
19079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
19089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        layer->drawForSreenShot();
19099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
191059119e658a12279e8fff508f8773843de2d90917Mathias Agopian
1911118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    hw.compositionComplete();
1912118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
19139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // back to main framebuffer
19149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
19159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_SCISSOR_TEST);
19169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDeleteFramebuffersOES(1, &name);
191759119e658a12279e8fff508f8773843de2d90917Mathias Agopian
19189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *textureName = tname;
19199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *uOut = u;
19209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *vOut = v;
19219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
19229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
192359119e658a12279e8fff508f8773843de2d90917Mathias Agopian
19249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// ---------------------------------------------------------------------------
192559119e658a12279e8fff508f8773843de2d90917Mathias Agopian
19269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::electronBeamOffAnimationImplLocked()
19279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
19289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // get screen geometry
19299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
19309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_w = hw.getWidth();
19319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_h = hw.getHeight();
1932a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    const Region screenBounds(hw.getBounds());
193359119e658a12279e8fff508f8773843de2d90917Mathias Agopian
19349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat u, v;
19359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLuint tname;
1936118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    status_t result = renderScreenToTextureLocked(0, &tname, &u, &v);
19379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (result != NO_ERROR) {
19389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return result;
19399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
194059119e658a12279e8fff508f8773843de2d90917Mathias Agopian
19419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat vtx[8];
1942a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    const GLfloat texCoords[4][2] = { {0,0}, {0,v}, {u,v}, {u,0} };
19439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
19449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
19459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
19469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1947b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1948b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
19499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
19509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
19519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glVertexPointer(2, GL_FLOAT, 0, vtx);
19529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
1953ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    /*
1954ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     * Texture coordinate mapping
1955ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *
1956ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *                 u
1957ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *    1 +----------+---+
1958ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |     |    |   |  image is inverted
1959ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |     V    |   |  w.r.t. the texture
1960ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *  1-v +----------+   |  coordinates
1961ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |              |
1962ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |              |
1963ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |              |
1964ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *    0 +--------------+
1965ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      0              1
1966ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *
1967ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     */
1968ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian
19699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class s_curve_interpolator {
19709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float nbFrames, s, v;
19719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
19729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        s_curve_interpolator(int nbFrames, float s)
19739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : nbFrames(1.0f / (nbFrames-1)), s(s),
19749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian          v(1.0f + expf(-s + 0.5f*s)) {
19759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
19769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float operator()(int f) {
19779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const float x = f * nbFrames;
19789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f;
19799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
19809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
19819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class v_stretch {
19839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
19849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
19859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        v_stretch(uint32_t hw_w, uint32_t hw_h)
19869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
19879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
19889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
19899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w + (hw_w * v);
19909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = hw_h - (hw_h * v);
19919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
19929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
1993ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[0] = x;         vtx[1] = y;
1994ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
1995ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
1996ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
19979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
19989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
19999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class h_stretch {
20019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
20029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
20039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        h_stretch(uint32_t hw_w, uint32_t hw_h)
20049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
200559119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
20069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
20079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w - (hw_w * v);
20089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = 1.0f;
20099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
20109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
2011ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[0] = x;         vtx[1] = y;
2012ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
2013ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
2014ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
20159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
20169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
20179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // the full animation is 24 frames
2019ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    char value[PROPERTY_VALUE_MAX];
2020ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    property_get("debug.sf.electron_frames", value, "24");
2021ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    int nbFrames = (atoi(value) + 1) >> 1;
2022ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    if (nbFrames <= 0) // just in case
2023ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian        nbFrames = 24;
2024ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian
20259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itr(nbFrames, 7.5f);
20269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itg(nbFrames, 8.0f);
20279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itb(nbFrames, 8.5f);
20289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    v_stretch vverts(hw_w, hw_h);
2030a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian
2031a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glMatrixMode(GL_TEXTURE);
2032a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glLoadIdentity();
2033a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glMatrixMode(GL_MODELVIEW);
2034a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glLoadIdentity();
2035a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian
20369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnable(GL_BLEND);
20379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBlendFunc(GL_ONE, GL_ONE);
20389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=0 ; i<nbFrames ; i++) {
20399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float x, y, w, h;
20409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vr = itr(i);
20419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vg = itg(i);
20429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vb = itb(i);
20439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // clear screen
20459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(1,1,1,1);
20469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
20479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glEnable(GL_TEXTURE_2D);
204859119e658a12279e8fff508f8773843de2d90917Mathias Agopian
20499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the red plane
20509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vr);
20519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(1,0,0,1);
20529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
20539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the green plane
20559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vg);
20569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,1,0,1);
20579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
20589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the blue plane
20609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vb);
20619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,0,1,1);
20629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
20639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the white highlight (we use the last vertices)
206559119e658a12279e8fff508f8773843de2d90917Mathias Agopian        glDisable(GL_TEXTURE_2D);
206659119e658a12279e8fff508f8773843de2d90917Mathias Agopian        glColorMask(1,1,1,1);
20679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColor4f(vg, vg, vg, 1);
20689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
20699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
20709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
20719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    h_stretch hverts(hw_w, hw_h);
20739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_BLEND);
20749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_TEXTURE_2D);
20759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
20769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=0 ; i<nbFrames ; i++) {
20779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float v = itg(i);
20789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hverts(vtx, v);
20799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
20809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColor4f(1-v, 1-v, 1-v, 1);
20819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
20829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
20839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
20849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
20869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnable(GL_SCISSOR_TEST);
20879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
20889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDeleteTextures(1, &tname);
2089a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    glDisable(GL_TEXTURE_2D);
2090c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_BLEND);
20919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
20929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
20939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::electronBeamOnAnimationImplLocked()
20959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
20969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    status_t result = PERMISSION_DENIED;
20979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
20999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return INVALID_OPERATION;
21009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // get screen geometry
21039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
21049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_w = hw.getWidth();
21059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_h = hw.getHeight();
21069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const Region screenBounds(hw.bounds());
21079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat u, v;
21099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLuint tname;
21109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    result = renderScreenToTextureLocked(0, &tname, &u, &v);
21119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (result != NO_ERROR) {
21129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return result;
21139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
21149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat vtx[8];
21169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const GLfloat texCoords[4][2] = { {0,v}, {0,0}, {u,0}, {u,v} };
21179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
21189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
21199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
21209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2121b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2122b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
21239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
21249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
21259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glVertexPointer(2, GL_FLOAT, 0, vtx);
21269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class s_curve_interpolator {
21289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float nbFrames, s, v;
21299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
21309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        s_curve_interpolator(int nbFrames, float s)
21319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : nbFrames(1.0f / (nbFrames-1)), s(s),
21329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian          v(1.0f + expf(-s + 0.5f*s)) {
21339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
21349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float operator()(int f) {
21359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const float x = f * nbFrames;
21369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f;
21379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
21389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
21399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class v_stretch {
21419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
21429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
21439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        v_stretch(uint32_t hw_w, uint32_t hw_h)
21449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
214559119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
21469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
21479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w + (hw_w * v);
21489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = hw_h - (hw_h * v);
21499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
21509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
21519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[0] = x;         vtx[1] = y;
21529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
21539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
21549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
21559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
21569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
21579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class h_stretch {
21599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
21609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
21619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        h_stretch(uint32_t hw_w, uint32_t hw_h)
21629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
21639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
21649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
21659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w - (hw_w * v);
21669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = 1.0f;
21679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
21689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
21699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[0] = x;         vtx[1] = y;
21709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
21719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
21729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
21739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
21749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
21759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2176a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian    // the full animation is 12 frames
2177a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian    int nbFrames = 8;
21789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itr(nbFrames, 7.5f);
21799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itg(nbFrames, 8.0f);
21809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itb(nbFrames, 8.5f);
21819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    h_stretch hverts(hw_w, hw_h);
21839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_BLEND);
21849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_TEXTURE_2D);
21859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
21869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=nbFrames-1 ; i>=0 ; i--) {
21879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float v = itg(i);
21889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hverts(vtx, v);
21899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
21909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColor4f(1-v, 1-v, 1-v, 1);
21919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
21929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
21939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
21949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2195a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian    nbFrames = 4;
21969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    v_stretch vverts(hw_w, hw_h);
21979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnable(GL_BLEND);
21989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBlendFunc(GL_ONE, GL_ONE);
21999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=nbFrames-1 ; i>=0 ; i--) {
22009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float x, y, w, h;
22019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vr = itr(i);
22029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vg = itg(i);
22039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vb = itb(i);
220459119e658a12279e8fff508f8773843de2d90917Mathias Agopian
22059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // clear screen
220659119e658a12279e8fff508f8773843de2d90917Mathias Agopian        glColorMask(1,1,1,1);
22079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
22089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glEnable(GL_TEXTURE_2D);
22099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the red plane
22119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vr);
22129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(1,0,0,1);
22139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
22149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the green plane
22169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vg);
22179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,1,0,1);
22189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
22199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the blue plane
22219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vb);
22229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,0,1,1);
22239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
22249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
222659119e658a12279e8fff508f8773843de2d90917Mathias Agopian    }
222759119e658a12279e8fff508f8773843de2d90917Mathias Agopian
22289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
22299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnable(GL_SCISSOR_TEST);
22309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
223159119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glDeleteTextures(1, &tname);
2232a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    glDisable(GL_TEXTURE_2D);
2233c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_BLEND);
223459119e658a12279e8fff508f8773843de2d90917Mathias Agopian
22359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
22369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
22379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// ---------------------------------------------------------------------------
22399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2240abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOffImplLocked(int32_t mode)
22419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
22429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    DisplayHardware& hw(graphicPlane(0).editDisplayHardware());
22439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (!hw.canDraw()) {
22449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // we're already off
22459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return NO_ERROR;
22469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
22477ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian
22487ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian    // turn off hwc while we're doing the animation
22497ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian    hw.getHwComposer().disable();
22507ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian    // and make sure to turn it back on (if needed) next time we compose
22517ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian    invalidateHwcGeometry();
22527ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian
2253abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    if (mode & ISurfaceComposer::eElectronBeamAnimationOff) {
2254abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        electronBeamOffAnimationImplLocked();
2255abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    }
2256abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian
2257abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    // always clear the whole screen at the end of the animation
2258abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    glClearColor(0,0,0,1);
2259abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    glDisable(GL_SCISSOR_TEST);
2260abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    glClear(GL_COLOR_BUFFER_BIT);
2261abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    glEnable(GL_SCISSOR_TEST);
2262abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    hw.flip( Region(hw.bounds()) );
2263abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian
2264015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian    return NO_ERROR;
226559119e658a12279e8fff508f8773843de2d90917Mathias Agopian}
226659119e658a12279e8fff508f8773843de2d90917Mathias Agopian
226759119e658a12279e8fff508f8773843de2d90917Mathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOff(int32_t mode)
226859119e658a12279e8fff508f8773843de2d90917Mathias Agopian{
226959119e658a12279e8fff508f8773843de2d90917Mathias Agopian    class MessageTurnElectronBeamOff : public MessageBase {
227059119e658a12279e8fff508f8773843de2d90917Mathias Agopian        SurfaceFlinger* flinger;
2271abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        int32_t mode;
227259119e658a12279e8fff508f8773843de2d90917Mathias Agopian        status_t result;
227359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    public:
2274abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        MessageTurnElectronBeamOff(SurfaceFlinger* flinger, int32_t mode)
2275abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            : flinger(flinger), mode(mode), result(PERMISSION_DENIED) {
227659119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
227759119e658a12279e8fff508f8773843de2d90917Mathias Agopian        status_t getResult() const {
227859119e658a12279e8fff508f8773843de2d90917Mathias Agopian            return result;
227959119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
228059119e658a12279e8fff508f8773843de2d90917Mathias Agopian        virtual bool handler() {
228159119e658a12279e8fff508f8773843de2d90917Mathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
2282abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            result = flinger->turnElectronBeamOffImplLocked(mode);
228359119e658a12279e8fff508f8773843de2d90917Mathias Agopian            return true;
228459119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
228559119e658a12279e8fff508f8773843de2d90917Mathias Agopian    };
228659119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2287abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    sp<MessageBase> msg = new MessageTurnElectronBeamOff(this, mode);
228859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    status_t res = postMessageSync(msg);
228959119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (res == NO_ERROR) {
229059119e658a12279e8fff508f8773843de2d90917Mathias Agopian        res = static_cast<MessageTurnElectronBeamOff*>( msg.get() )->getResult();
22919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // work-around: when the power-manager calls us we activate the
22939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // animation. eventually, the "on" animation will be called
22949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // by the power-manager itself
2295abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        mElectronBeamAnimationMode = mode;
229659119e658a12279e8fff508f8773843de2d90917Mathias Agopian    }
229759119e658a12279e8fff508f8773843de2d90917Mathias Agopian    return res;
229859119e658a12279e8fff508f8773843de2d90917Mathias Agopian}
229959119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
2301edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2302abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOnImplLocked(int32_t mode)
23039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
23049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    DisplayHardware& hw(graphicPlane(0).editDisplayHardware());
23059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (hw.canDraw()) {
23069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // we're already on
23079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return NO_ERROR;
23089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
2309abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    if (mode & ISurfaceComposer::eElectronBeamAnimationOn) {
2310abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        electronBeamOnAnimationImplLocked();
2311abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    }
2312a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian
2313a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian    // make sure to redraw the whole screen when the animation is done
2314a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian    mDirtyRegion.set(hw.bounds());
231599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    signalTransaction();
2316a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian
2317015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian    return NO_ERROR;
23189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
23199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
23209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOn(int32_t mode)
23219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
23229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class MessageTurnElectronBeamOn : public MessageBase {
23239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        SurfaceFlinger* flinger;
2324abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        int32_t mode;
23259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        status_t result;
23269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
2327abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        MessageTurnElectronBeamOn(SurfaceFlinger* flinger, int32_t mode)
2328abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            : flinger(flinger), mode(mode), result(PERMISSION_DENIED) {
23299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
23309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        status_t getResult() const {
23319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return result;
23329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
23339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        virtual bool handler() {
23349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
2335abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            result = flinger->turnElectronBeamOnImplLocked(mode);
23369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return true;
23379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
23389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
23399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2340abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    postMessageAsync( new MessageTurnElectronBeamOn(this, mode) );
23419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
23429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
23439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
23449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// ---------------------------------------------------------------------------
23459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
234674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopianstatus_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy,
234774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        sp<IMemoryHeap>* heap,
234874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t* w, uint32_t* h, PixelFormat* f,
2349bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t sw, uint32_t sh,
2350bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ, uint32_t maxLayerZ)
235174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{
235274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    status_t result = PERMISSION_DENIED;
235374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
235474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // only one display supported for now
235599ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten    if (CC_UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
235674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return BAD_VALUE;
235774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
235874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
235974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return INVALID_OPERATION;
236074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
236174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // get screen geometry
236274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const DisplayHardware& hw(graphicPlane(dpy).displayHardware());
236374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const uint32_t hw_w = hw.getWidth();
236474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const uint32_t hw_h = hw.getHeight();
236574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
236674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    if ((sw > hw_w) || (sh > hw_h))
236774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return BAD_VALUE;
236874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
236974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    sw = (!sw) ? hw_w : sw;
237074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    sh = (!sh) ? hw_h : sh;
237174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const size_t size = sw * sh * 4;
237274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
23739d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block    //ALOGD("screenshot: sw=%d, sh=%d, minZ=%d, maxZ=%d",
23741c71a47a6db679a3212f0c99e14f330d6da500faMathias Agopian    //        sw, sh, minLayerZ, maxLayerZ);
2375c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
237674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // make sure to clear all GL error flags
237774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    while ( glGetError() != GL_NO_ERROR ) ;
237874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
237974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // create a FBO
238074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    GLuint name, tname;
238174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glGenRenderbuffersOES(1, &tname);
238274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindRenderbufferOES(GL_RENDERBUFFER_OES, tname);
238374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA8_OES, sw, sh);
238474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glGenFramebuffersOES(1, &name);
238574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
238674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES,
238774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, tname);
238874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
238974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
2390c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
239174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    if (status == GL_FRAMEBUFFER_COMPLETE_OES) {
239274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
239374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // invert everything, b/c glReadPixel() below will invert the FB
239474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glViewport(0, 0, sw, sh);
2395f653b897a449e10d6cbfb6e0812f7b0bb02d6482Mathias Agopian        glScissor(0, 0, sw, sh);
2396ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian        glEnable(GL_SCISSOR_TEST);
239774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_PROJECTION);
239874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glPushMatrix();
239974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glLoadIdentity();
2400ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian        glOrthof(0, hw_w, hw_h, 0, 0, 1);
240174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_MODELVIEW);
240274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
240374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // redraw the screen entirely...
240474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glClearColor(0,0,0,1);
240574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
2406f653b897a449e10d6cbfb6e0812f7b0bb02d6482Mathias Agopian
24079575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        const LayerVector& layers(mDrawingState.layersSortedByZ);
24089575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        const size_t count = layers.size();
240974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        for (size_t i=0 ; i<count ; ++i) {
241074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            const sp<LayerBase>& layer(layers[i]);
2411b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian            const uint32_t flags = layer->drawingState().flags;
2412b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian            if (!(flags & ISurfaceComposer::eLayerHidden)) {
2413b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                const uint32_t z = layer->drawingState().z;
2414b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                if (z >= minLayerZ && z <= maxLayerZ) {
2415b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                    layer->drawForSreenShot();
2416b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                }
2417bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian            }
241874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        }
241974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
242074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // XXX: this is needed on tegra
2421ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian        glEnable(GL_SCISSOR_TEST);
242274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glScissor(0, 0, sw, sh);
242374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
242474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // check for errors and return screen capture
242574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        if (glGetError() != GL_NO_ERROR) {
242674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // error while rendering
242774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            result = INVALID_OPERATION;
242874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        } else {
242974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // allocate shared memory large enough to hold the
243074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // screen capture
243174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            sp<MemoryHeapBase> base(
243274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    new MemoryHeapBase(size, 0, "screen-capture") );
243374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            void* const ptr = base->getBase();
243474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            if (ptr) {
243574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                // capture the screen with glReadPixels()
243674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                glReadPixels(0, 0, sw, sh, GL_RGBA, GL_UNSIGNED_BYTE, ptr);
243774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                if (glGetError() == GL_NO_ERROR) {
243874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *heap = base;
243974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *w = sw;
244074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *h = sh;
244174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *f = PIXEL_FORMAT_RGBA_8888;
244274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    result = NO_ERROR;
244374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                }
244474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            } else {
244574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                result = NO_MEMORY;
244674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            }
244774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        }
244874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glEnable(GL_SCISSOR_TEST);
244974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glViewport(0, 0, hw_w, hw_h);
245074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_PROJECTION);
245174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glPopMatrix();
245274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_MODELVIEW);
245374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    } else {
245474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        result = BAD_VALUE;
245574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    }
245674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
245774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // release FBO resources
245874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
245974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glDeleteRenderbuffersOES(1, &tname);
246074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glDeleteFramebuffersOES(1, &name);
2461e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian
2462e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian    hw.compositionComplete();
2463e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian
24649d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block    // ALOGD("screenshot: result = %s", result<0 ? strerror(result) : "OK");
2465c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
246674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    return result;
246774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian}
246874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
246974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
24701b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopianstatus_t SurfaceFlinger::captureScreen(DisplayID dpy,
24711b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        sp<IMemoryHeap>* heap,
247274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t* width, uint32_t* height, PixelFormat* format,
2473bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t sw, uint32_t sh,
2474bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ, uint32_t maxLayerZ)
24751b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian{
24761b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    // only one display supported for now
247799ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten    if (CC_UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
24781b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        return BAD_VALUE;
24791b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
24801b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
24811b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        return INVALID_OPERATION;
24821b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
24831b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    class MessageCaptureScreen : public MessageBase {
24841b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        SurfaceFlinger* flinger;
24851b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        DisplayID dpy;
24861b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        sp<IMemoryHeap>* heap;
24871b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        uint32_t* w;
24881b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        uint32_t* h;
24891b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        PixelFormat* f;
249074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t sw;
249174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t sh;
2492bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ;
2493bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t maxLayerZ;
24941b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        status_t result;
24951b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    public:
24961b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        MessageCaptureScreen(SurfaceFlinger* flinger, DisplayID dpy,
249774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                sp<IMemoryHeap>* heap, uint32_t* w, uint32_t* h, PixelFormat* f,
2498bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                uint32_t sw, uint32_t sh,
2499bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                uint32_t minLayerZ, uint32_t maxLayerZ)
25001b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            : flinger(flinger), dpy(dpy),
2501bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              heap(heap), w(w), h(h), f(f), sw(sw), sh(sh),
2502bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              minLayerZ(minLayerZ), maxLayerZ(maxLayerZ),
2503bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              result(PERMISSION_DENIED)
25041b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
25051b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
25061b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        status_t getResult() const {
25071b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            return result;
25081b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
25091b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        virtual bool handler() {
25101b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
25111b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
25121b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            // if we have secure windows, never allow the screen capture
25131b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            if (flinger->mSecureFrameBuffer)
25141b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                return true;
25151b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
251674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            result = flinger->captureScreenImplLocked(dpy,
2517bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                    heap, w, h, f, sw, sh, minLayerZ, maxLayerZ);
25181b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
25191b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            return true;
25201b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
25211b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    };
25221b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
25231b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    sp<MessageBase> msg = new MessageCaptureScreen(this,
2524bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian            dpy, heap, width, height, format, sw, sh, minLayerZ, maxLayerZ);
25251b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    status_t res = postMessageSync(msg);
25261b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    if (res == NO_ERROR) {
25271b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        res = static_cast<MessageCaptureScreen*>( msg.get() )->getResult();
25281b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    }
25291b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    return res;
25301b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian}
25311b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
25321b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// ---------------------------------------------------------------------------
25331b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
2534b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<Layer> SurfaceFlinger::getLayer(const sp<ISurface>& sur) const
2535edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2536b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<Layer> result;
2537b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    Mutex::Autolock _l(mStateLock);
2538b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    result = mLayerMap.valueFor( sur->asBinder() ).promote();
2539b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return result;
2540b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
25417303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
2542b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// ---------------------------------------------------------------------------
254396f0819f81293076e652792794a961543e6750d7Mathias Agopian
2544b7e930db175c192464cebdeb49eb56cf6dd60114Mathias AgopianClient::Client(const sp<SurfaceFlinger>& flinger)
2545b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    : mFlinger(flinger), mNameGenerator(1)
2546b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{
2547edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2548edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
254996f0819f81293076e652792794a961543e6750d7Mathias AgopianClient::~Client()
255096f0819f81293076e652792794a961543e6750d7Mathias Agopian{
255196f0819f81293076e652792794a961543e6750d7Mathias Agopian    const size_t count = mLayers.size();
255296f0819f81293076e652792794a961543e6750d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
255396f0819f81293076e652792794a961543e6750d7Mathias Agopian        sp<LayerBaseClient> layer(mLayers.valueAt(i).promote());
255496f0819f81293076e652792794a961543e6750d7Mathias Agopian        if (layer != 0) {
255596f0819f81293076e652792794a961543e6750d7Mathias Agopian            mFlinger->removeLayer(layer);
255696f0819f81293076e652792794a961543e6750d7Mathias Agopian        }
2557edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2558edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2559076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
256096f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t Client::initCheck() const {
2561b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return NO_ERROR;
2562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2563076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
25644f113740180b6512b43723c4728f262882dc9b45Mathias Agopiansize_t Client::attachLayer(const sp<LayerBaseClient>& layer)
2565edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
25664f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    Mutex::Autolock _l(mLock);
25674f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    size_t name = mNameGenerator++;
256896f0819f81293076e652792794a961543e6750d7Mathias Agopian    mLayers.add(name, layer);
256996f0819f81293076e652792794a961543e6750d7Mathias Agopian    return name;
2570edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2571edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2572b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianvoid Client::detachLayer(const LayerBaseClient* layer)
257396f0819f81293076e652792794a961543e6750d7Mathias Agopian{
25744f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    Mutex::Autolock _l(mLock);
257596f0819f81293076e652792794a961543e6750d7Mathias Agopian    // we do a linear search here, because this doesn't happen often
257696f0819f81293076e652792794a961543e6750d7Mathias Agopian    const size_t count = mLayers.size();
257796f0819f81293076e652792794a961543e6750d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
257896f0819f81293076e652792794a961543e6750d7Mathias Agopian        if (mLayers.valueAt(i) == layer) {
257996f0819f81293076e652792794a961543e6750d7Mathias Agopian            mLayers.removeItemsAt(i, 1);
258096f0819f81293076e652792794a961543e6750d7Mathias Agopian            break;
258196f0819f81293076e652792794a961543e6750d7Mathias Agopian        }
258296f0819f81293076e652792794a961543e6750d7Mathias Agopian    }
258396f0819f81293076e652792794a961543e6750d7Mathias Agopian}
25844f113740180b6512b43723c4728f262882dc9b45Mathias Agopiansp<LayerBaseClient> Client::getLayerUser(int32_t i) const
25854f113740180b6512b43723c4728f262882dc9b45Mathias Agopian{
25864f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    Mutex::Autolock _l(mLock);
2587076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBaseClient> lbc;
25884f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    wp<LayerBaseClient> layer(mLayers.valueFor(i));
258996f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (layer != 0) {
259096f0819f81293076e652792794a961543e6750d7Mathias Agopian        lbc = layer.promote();
2591e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE_IF(lbc==0, "getLayerUser(name=%d) is dead", int(i));
2592076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
2593076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return lbc;
2594edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2595edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2596a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
2597a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianstatus_t Client::onTransact(
2598a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
2599a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian{
2600a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // these must be checked
2601a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     IPCThreadState* ipc = IPCThreadState::self();
2602a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     const int pid = ipc->getCallingPid();
2603a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     const int uid = ipc->getCallingUid();
2604a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     const int self_pid = getpid();
260599ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten     if (CC_UNLIKELY(pid != self_pid && uid != AID_GRAPHICS && uid != 0)) {
2606a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian         // we're called from a different process, do the real check
260799b49840d309727678b77403d6cc9f920111623fMathias Agopian         if (!PermissionCache::checkCallingPermission(sAccessSurfaceFlinger))
2608a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian         {
2609e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block             ALOGE("Permission Denial: "
2610a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                     "can't openGlobalTransaction pid=%d, uid=%d", pid, uid);
2611a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian             return PERMISSION_DENIED;
2612a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian         }
2613a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     }
2614a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     return BnSurfaceComposerClient::onTransact(code, data, reply, flags);
2615edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2616a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
2617a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
261896f0819f81293076e652792794a961543e6750d7Mathias Agopiansp<ISurface> Client::createSurface(
26190ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        ISurfaceComposerClient::surface_data_t* params,
2620b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        const String8& name,
2621b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
2622edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t flags)
2623edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2624b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    /*
2625a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     * createSurface must be called from the GL thread so that it can
2626a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian     * have access to the GL context.
2627b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     */
2628b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
2629a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    class MessageCreateSurface : public MessageBase {
2630a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        sp<ISurface> result;
2631a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        SurfaceFlinger* flinger;
2632a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        ISurfaceComposerClient::surface_data_t* params;
2633a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        Client* client;
2634a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        const String8& name;
2635a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        DisplayID display;
2636a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        uint32_t w, h;
2637a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        PixelFormat format;
2638a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        uint32_t flags;
2639a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    public:
2640a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        MessageCreateSurface(SurfaceFlinger* flinger,
2641a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                ISurfaceComposerClient::surface_data_t* params,
2642a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                const String8& name, Client* client,
2643a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
2644a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                uint32_t flags)
2645a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            : flinger(flinger), params(params), client(client), name(name),
2646a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian              display(display), w(w), h(h), format(format), flags(flags)
2647a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        {
2648579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        }
2649a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        sp<ISurface> getResult() const { return result; }
2650a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        virtual bool handler() {
2651a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            result = flinger->createSurface(params, name, client,
2652a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                    display, w, h, format, flags);
2653a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            return true;
2654b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        }
2655a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    };
2656b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
2657a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    sp<MessageBase> msg = new MessageCreateSurface(mFlinger.get(),
2658a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            params, name, this, display, w, h, format, flags);
2659a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    mFlinger->postMessageSync(msg);
2660a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    return static_cast<MessageCreateSurface*>( msg.get() )->getResult();
2661b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
2662a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianstatus_t Client::destroySurface(SurfaceID sid) {
2663a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    return mFlinger->removeSurface(this, sid);
2664b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
2665b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
2666b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// ---------------------------------------------------------------------------
2667edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
26689a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::GraphicBufferAlloc() {}
26699a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
26709a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::~GraphicBufferAlloc() {}
26719a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
26729a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h,
2673d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        PixelFormat format, uint32_t usage, status_t* error) {
26749a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(w, h, format, usage));
26759a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    status_t err = graphicBuffer->initCheck();
2676d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian    *error = err;
2677a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (err != 0 || graphicBuffer->handle == 0) {
2678d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        if (err == NO_MEMORY) {
2679d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian            GraphicBuffer::dumpAllocationsToSystemLog();
2680d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        }
2681e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE("GraphicBufferAlloc::createGraphicBuffer(w=%d, h=%d) "
2682a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian             "failed (%s), handle=%p",
2683a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                w, h, strerror(-err), graphicBuffer->handle);
26849a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis        return 0;
26859a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    }
26869a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    return graphicBuffer;
26879a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis}
26889a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
26899a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis// ---------------------------------------------------------------------------
26909a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
2691edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane::GraphicPlane()
2692edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    : mHw(0)
2693edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2694edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2695edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2696edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane::~GraphicPlane() {
2697edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    delete mHw;
2698edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2699edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2700edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool GraphicPlane::initialized() const {
2701edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return mHw ? true : false;
2702edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2703edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
27042b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianint GraphicPlane::getWidth() const {
27052b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    return mWidth;
2706edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2707edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
27082b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianint GraphicPlane::getHeight() const {
27092b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    return mHeight;
27102b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian}
27112b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
27122b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianvoid GraphicPlane::setDisplayHardware(DisplayHardware *hw)
27132b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian{
27142b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mHw = hw;
27152b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
27162b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    // initialize the display orientation transform.
27172b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    // it's a constant that should come from the display driver.
27182b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    int displayOrientation = ISurfaceComposer::eOrientationDefault;
27192b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    char property[PROPERTY_VALUE_MAX];
27202b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    if (property_get("ro.sf.hwrotation", property, NULL) > 0) {
27212b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        //displayOrientation
27222b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        switch (atoi(property)) {
27232b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        case 90:
27242b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            displayOrientation = ISurfaceComposer::eOrientation90;
27252b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            break;
27262b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        case 270:
27272b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            displayOrientation = ISurfaceComposer::eOrientation270;
27282b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            break;
27292b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        }
27302b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    }
27312b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
27322b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float w = hw->getWidth();
27332b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float h = hw->getHeight();
27342b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    GraphicPlane::orientationToTransfrom(displayOrientation, w, h,
27352b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            &mDisplayTransform);
27362b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    if (displayOrientation & ISurfaceComposer::eOrientationSwapMask) {
27372b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayWidth = h;
27382b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayHeight = w;
27392b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    } else {
27402b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayWidth = w;
27412b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayHeight = h;
27422b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    }
27432b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
27442b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    setOrientation(ISurfaceComposer::eOrientationDefault);
2745edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2746edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2747edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t GraphicPlane::orientationToTransfrom(
2748edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int orientation, int w, int h, Transform* tr)
2749eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian{
2750eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    uint32_t flags = 0;
2751edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (orientation) {
2752edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientationDefault:
2753eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_0;
2754eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        break;
2755edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientation90:
2756eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_90;
2757edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
2758edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientation180:
2759eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_180;
2760edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
2761edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientation270:
2762eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_270;
2763edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
2764edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    default:
2765edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return BAD_VALUE;
2766edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2767eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    tr->set(flags, w, h);
2768edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
2769edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2770edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2771edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t GraphicPlane::setOrientation(int orientation)
2772edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2773edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // If the rotation can be handled in hardware, this is where
2774edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // the magic should happen.
27752b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
27762b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const DisplayHardware& hw(displayHardware());
27772b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float w = mDisplayWidth;
27782b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float h = mDisplayHeight;
27792b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mWidth = int(w);
27802b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mHeight = int(h);
27812b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
27822b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    Transform orientationTransform;
2783eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    GraphicPlane::orientationToTransfrom(orientation, w, h,
2784eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian            &orientationTransform);
2785eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    if (orientation & ISurfaceComposer::eOrientationSwapMask) {
2786eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        mWidth = int(h);
2787eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        mHeight = int(w);
2788edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2789eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian
27900d1318b974feba2e6ff13e36a1781343c2fce045Mathias Agopian    mOrientation = orientation;
27912b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mGlobalTransform = mDisplayTransform * orientationTransform;
2792edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
2793edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2794edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2795edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst DisplayHardware& GraphicPlane::displayHardware() const {
2796edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return *mHw;
2797edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2798edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
279959119e658a12279e8fff508f8773843de2d90917Mathias AgopianDisplayHardware& GraphicPlane::editDisplayHardware() {
280059119e658a12279e8fff508f8773843de2d90917Mathias Agopian    return *mHw;
280159119e658a12279e8fff508f8773843de2d90917Mathias Agopian}
280259119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2803edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst Transform& GraphicPlane::transform() const {
2804edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return mGlobalTransform;
2805edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2806edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2807076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias AgopianEGLDisplay GraphicPlane::getEGLDisplay() const {
2808076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return mHw->getEGLDisplay();
2809076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
2810076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
2811edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
2812edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2813edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
2814