SurfaceFlinger.cpp revision ef19414bd8b77a26f5751f3845be79025a8263fe
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"
53db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian#include "Client.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>
66ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian#include <gui/BitTube.h>
67a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
68bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian#define EGL_VERSION_HW_ANDROID  0x3143
69bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DISPLAY_COUNT       1
71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
73edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
74edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
7599b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sHardwareTest("android.permission.HARDWARE_TEST");
7699b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER");
7799b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER");
7899b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sDump("android.permission.DUMP");
7999b49840d309727678b77403d6cc9f920111623fMathias Agopian
8099b49840d309727678b77403d6cc9f920111623fMathias Agopian// ---------------------------------------------------------------------------
8199b49840d309727678b77403d6cc9f920111623fMathias Agopian
82edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::SurfaceFlinger()
83edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    :   BnSurfaceComposer(), Thread(false),
84edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mTransactionFlags(0),
8528378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        mTransationPending(false),
86076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved(false),
87edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mBootTime(systemTime()),
88edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mVisibleRegionsDirty(false),
89a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        mHwWorkListDirty(false),
90abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        mElectronBeamAnimationMode(0),
91edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDebugRegion(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        mSecureFrameBuffer(0)
101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    init();
103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::init()
106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
107a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI("SurfaceFlinger is starting");
108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // debugging stuff...
110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char value[PROPERTY_VALUE_MAX];
1118afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    property_get("debug.sf.showupdates", value, "0");
113edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDebugRegion = atoi(value);
1148afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
1153854ed549012f2abf8fea7b0e6db30b104ea5547Colin Cross#ifdef DDMS_DEBUGGING
1168afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    property_get("debug.sf.ddms", value, "0");
1178afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    mDebugDDMS = atoi(value);
1188afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    if (mDebugDDMS) {
1198afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian        DdmConnection::start(getServiceName());
1208afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    }
1215df996211d4e263feb862121cfafa7f9c8eeda68Mathias Agopian#else
1225df996211d4e263feb862121cfafa7f9c8eeda68Mathias Agopian#warning "DDMS_DEBUGGING disabled"
1233854ed549012f2abf8fea7b0e6db30b104ea5547Colin Cross#endif
1248afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
125a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI_IF(mDebugRegion,       "showupdates enabled");
126a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI_IF(mDebugDDMS,         "DDMS debugging enabled");
127edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
12999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::onFirstRef()
13099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
13199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.init(this);
13299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
13399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY);
13499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
13599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // Wait for the main thread to be done with its initialization
13699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mReadyToRunBarrier.wait();
13799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
13899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
13999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::~SurfaceFlinger()
141edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
142edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDeleteTextures(1, &mWormholeTexName);
143edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
14599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::binderDied(const wp<IBinder>& who)
14699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
14799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // the window manager died on us. prepare its eulogy.
14899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
14999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // reset screen orientation
15099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    Vector<ComposerState> state;
15199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    setTransactionState(state, eOrientationDefault, 0);
15299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
15399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // restart the boot-animation
154a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    startBootAnim();
15599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
15699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
1577303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopiansp<IMemoryHeap> SurfaceFlinger::getCblk() const
158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1597303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    return mServerHeap;
160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1627e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopiansp<ISurfaceComposerClient> SurfaceFlinger::createConnection()
163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
16496f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<ISurfaceComposerClient> bclient;
16596f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<Client> client(new Client(this));
16696f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = client->initCheck();
16796f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR) {
16896f0819f81293076e652792794a961543e6750d7Mathias Agopian        bclient = client;
169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return bclient;
171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1739a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc()
1749a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis{
1759a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc());
1769a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    return gba;
1779a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis}
178b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst GraphicPlane& SurfaceFlinger::graphicPlane(int dpy) const
180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
181e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block    ALOGE_IF(uint32_t(dpy) >= DISPLAY_COUNT, "Invalid DisplayID %d", dpy);
182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(mGraphicPlanes[dpy]);
183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return plane;
184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane& SurfaceFlinger::graphicPlane(int dpy)
187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return const_cast<GraphicPlane&>(
189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const_cast<SurfaceFlinger const *>(this)->graphicPlane(dpy));
190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::bootFinished()
193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t now = systemTime();
195edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t duration = now - mBootTime;
196a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
1973330b203039dea366d4981db1408a460134b2d2cMathias Agopian    mBootFinished = true;
1981f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
1991f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // wait patiently for the window manager death
2001f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    const String16 name("window");
2011f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    sp<IBinder> window(defaultServiceManager()->getService(name));
2021f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    if (window != 0) {
2031f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian        window->linkToDeath(this);
2041f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    }
2051f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
2061f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // stop boot animation
207a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // formerly we would just kill the process, but we now ask it to exit so it
208a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // can choose where to stop the animation.
209a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("service.bootanim.exit", "1");
210edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic inline uint16_t pack565(int r, int g, int b) {
213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return (r<<11)|(g<<5)|b;
214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::readyToRun()
217edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
218a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI(   "SurfaceFlinger's main thread ready to run. "
219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            "Initializing graphics H/W...");
220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // we only support one display currently
222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int dpy = 0;
223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    {
225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // initialize the main display
226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GraphicPlane& plane(graphicPlane(dpy));
227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        DisplayHardware* const hw = new DisplayHardware(this, dpy);
228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        plane.setDisplayHardware(hw);
229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2317303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    // create the shared control-block
2327303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    mServerHeap = new MemoryHeapBase(4096,
2337303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian            MemoryHeapBase::READ_ONLY, "SurfaceFlinger read-only heap");
234e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block    ALOGE_IF(mServerHeap==0, "can't create shared memory dealer");
2358b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
2367303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    mServerCblk = static_cast<surface_flinger_cblk_t*>(mServerHeap->getBase());
237e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block    ALOGE_IF(mServerCblk==0, "can't get to shared control block's address");
2388b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
2397303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    new(mServerCblk) surface_flinger_cblk_t;
2407303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize primary screen
242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // (other display should be initialized in the same manner, but
243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // asynchronously, as they could come and go. None of this is supported
244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // yet).
245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(graphicPlane(dpy));
246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw = plane.displayHardware();
247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint32_t w = hw.getWidth();
248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint32_t h = hw.getHeight();
249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint32_t f = hw.getFormat();
250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    hw.makeCurrent();
251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize the shared control block
253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mServerCblk->connected |= 1<<dpy;
254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    display_cblk_t* dcblk = mServerCblk->displays + dpy;
255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    memset(dcblk, 0, sizeof(display_cblk_t));
2562b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    dcblk->w            = plane.getWidth();
2572b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    dcblk->h            = plane.getHeight();
258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->format       = f;
259edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->orientation  = ISurfaceComposer::eOrientationDefault;
260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->xdpi         = hw.getDpiX();
261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->ydpi         = hw.getDpiY();
262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->fps          = hw.getRefreshRate();
263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->density      = hw.getDensity();
264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
265edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // Initialize OpenGL|ES
266edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
2678b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber    glPixelStorei(GL_PACK_ALIGNMENT, 4);
268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glEnableClientState(GL_VERTEX_ARRAY);
269edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    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);
305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     *  We're now ready to accept clients...
308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
310d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian    mReadyToRunBarrier.open();
311d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
312a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    // start boot animation
313a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    startBootAnim();
3148b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
315edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
318a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopianvoid SurfaceFlinger::startBootAnim() {
319a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // start boot animation
320a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("service.bootanim.exit", "0");
321a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("ctl.start", "bootanim");
322a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian}
323a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian
324edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
325d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
326582270d69db94286a248bd829f1ae6f910d45124Jamie Gennisbool SurfaceFlinger::authenticateSurfaceTexture(
327582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis        const sp<ISurfaceTexture>& surfaceTexture) const {
328134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    Mutex::Autolock _l(mStateLock);
329582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis    sp<IBinder> surfaceTextureBinder(surfaceTexture->asBinder());
330134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
331134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // Check the visible layer list for the ISurface
332134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
333134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    size_t count = currentLayers.size();
334134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    for (size_t i=0 ; i<count ; i++) {
335134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        const sp<LayerBase>& layer(currentLayers[i]);
336134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        sp<LayerBaseClient> lbc(layer->getLayerBaseClient());
337582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis        if (lbc != NULL) {
338582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder();
339582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            if (lbcBinder == surfaceTextureBinder) {
340582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis                return true;
341582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            }
342134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        }
343134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    }
344134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
345134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // Check the layers in the purgatory.  This check is here so that if a
346582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis    // SurfaceTexture gets destroyed before all the clients are done using it,
347582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis    // the error will not be reported as "surface XYZ is not authenticated", but
348134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // will instead fail later on when the client tries to use the surface,
349134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // which should be reported as "surface XYZ returned an -ENODEV".  The
350134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // purgatorized layers are no less authentic than the visible ones, so this
351134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // should not cause any harm.
352134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    size_t purgatorySize =  mLayerPurgatory.size();
353134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    for (size_t i=0 ; i<purgatorySize ; i++) {
354134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
355134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        sp<LayerBaseClient> lbc(layer->getLayerBaseClient());
356582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis        if (lbc != NULL) {
357582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder();
358582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            if (lbcBinder == surfaceTextureBinder) {
359582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis                return true;
360582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            }
361134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        }
362134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    }
363134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
364134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    return false;
365134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis}
366134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
367d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian// ----------------------------------------------------------------------------
368d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
369d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopiansp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection() {
3708aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian    return mEventThread->createEventConnection();
371bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian}
372bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
373edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
37499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
37599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::waitForEvent() {
37699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.waitMessage();
37799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
37899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
37999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalTransaction() {
38099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.invalidate();
38199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
38299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
38399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalLayerUpdate() {
38499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.invalidate();
38599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
38699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
38799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalRefresh() {
38899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.refresh();
38999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
39099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
39199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg,
39299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        nsecs_t reltime, uint32_t flags) {
39399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return mEventQueue.postMessage(msg, reltime);
39499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
39599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
39699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,
39799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        nsecs_t reltime, uint32_t flags) {
39899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    status_t res = mEventQueue.postMessage(msg, reltime);
39999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    if (res == NO_ERROR) {
40099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        msg->wait();
40199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    }
40299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return res;
40399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
404edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
405edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool SurfaceFlinger::threadLoop()
406edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
407edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    waitForEvent();
40899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return true;
40999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
410edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
41199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::onMessageReceived(int32_t what)
41299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
4131c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
41499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    switch (what) {
41569a655caef30663403802281210363f643ceb946Mathias Agopian        case MessageQueue::REFRESH: {
41669a655caef30663403802281210363f643ceb946Mathias Agopian//        case MessageQueue::INVALIDATE: {
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
42769a655caef30663403802281210363f643ceb946Mathias Agopian//            signalRefresh();
42869a655caef30663403802281210363f643ceb946Mathias Agopian//
42969a655caef30663403802281210363f643ceb946Mathias Agopian//        } break;
43069a655caef30663403802281210363f643ceb946Mathias Agopian//
43169a655caef30663403802281210363f643ceb946Mathias Agopian//        case MessageQueue::REFRESH: {
4323a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian
433c9ca7011501cb8730ce4e6e527cb402adb7a0178Mathias Agopian            handleRefresh();
434a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
435303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian            const DisplayHardware& hw(graphicPlane(0).displayHardware());
436303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian
43769a655caef30663403802281210363f643ceb946Mathias Agopian//            if (mDirtyRegion.isEmpty()) {
43869a655caef30663403802281210363f643ceb946Mathias Agopian//                return;
43969a655caef30663403802281210363f643ceb946Mathias Agopian//            }
44069a655caef30663403802281210363f643ceb946Mathias 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();
475ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall    HWComposer& hwc(graphicPlane(0).displayHardware().getHwComposer());
476ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall    if (hwc.initCheck() == NO_ERROR) {
477ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall        HWComposer::LayerListIterator cur = hwc.begin();
478ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall        const HWComposer::LayerListIterator end = hwc.end();
479ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall        for (size_t i = 0; cur != end && i < numLayers; ++i, ++cur) {
480ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall            mVisibleLayersSortedByZ[i]->onLayerDisplayed(&*cur);
481ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall        }
482ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall    } else {
483ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall        for (size_t i = 0; i < numLayers; i++) {
484ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall            mVisibleLayersSortedByZ[i]->onLayerDisplayed(NULL);
485ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall        }
486e8696a40e09b24b634214684d18526187b316a2fJamie Gennis    }
487e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
488a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mLastSwapBufferTime = systemTime() - now;
489a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = 0;
490a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mSwapRegion.clear();
491edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
492edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
493edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
494edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
495841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
496841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
497ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    Mutex::Autolock _l(mStateLock);
498ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    const nsecs_t now = systemTime();
499ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = now;
500ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
501ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // Here we're guaranteed that some transaction flags are set
502ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // so we can call handleTransactionLocked() unconditionally.
503ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // We call getTransactionFlags(), which will also clear the flags,
504ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // with mStateLock held to guarantee that mCurrentState won't change
505ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // until the transaction is committed.
506ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
507ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
508ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    transactionFlags = getTransactionFlags(mask);
509ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    handleTransactionLocked(transactionFlags);
510ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
511ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mLastTransactionTime = systemTime() - now;
512ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = 0;
513ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    invalidateHwcGeometry();
514ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // here the transaction has been committed
5153d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian}
516edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
517ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopianvoid SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
5183d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{
5193d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    const LayerVector& currentLayers(mCurrentState.layersSortedByZ);
520edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t count = currentLayers.size();
521edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
522edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
523edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Traversal of the children
524edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * (perform the transaction for each of them if needed)
525edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
526edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
527edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const bool layersNeedTransaction = transactionFlags & eTraversalNeeded;
528edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (layersNeedTransaction) {
529edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (size_t i=0 ; i<count ; i++) {
530076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            const sp<LayerBase>& layer = currentLayers[i];
531edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
532edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (!trFlags) continue;
533edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
534edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const uint32_t flags = layer->doTransaction(0);
535edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (flags & Layer::eVisibleRegion)
536edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mVisibleRegionsDirty = true;
537edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
538edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
539edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
540edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
541edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Perform our own transaction if needed
542edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
543edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
544edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (transactionFlags & eTransactionNeeded) {
545edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (mCurrentState.orientation != mDrawingState.orientation) {
546edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // the orientation has changed, recompute all visible regions
547edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // and invalidate everything.
548edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
549edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int dpy = 0;
550edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int orientation = mCurrentState.orientation;
55121230c6410bdab13cd2bd274da54b1e4061b6035Jeff Brown            // Currently unused: const uint32_t flags = mCurrentState.orientationFlags;
552edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            GraphicPlane& plane(graphicPlane(dpy));
553edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            plane.setOrientation(orientation);
554edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
555edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // update the shared control block
556edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const DisplayHardware& hw(plane.displayHardware());
557edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            volatile display_cblk_t* dcblk = mServerCblk->displays + dpy;
558edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dcblk->orientation = orientation;
5592b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            dcblk->w = plane.getWidth();
5602b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            dcblk->h = plane.getHeight();
561edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
563edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mDirtyRegion.set(hw.bounds());
564edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
565edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5660aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        if (currentLayers.size() > mDrawingState.layersSortedByZ.size()) {
5670aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            // layers have been added
568edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
569edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
570edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5710aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        // some layers might have been removed, so
5720aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        // we need to update the regions they're exposing.
5730aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        if (mLayersRemoved) {
57448d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian            mLayersRemoved = false;
575edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
5760aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            const LayerVector& previousLayers(mDrawingState.layersSortedByZ);
5773d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian            const size_t count = previousLayers.size();
5783d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian            for (size_t i=0 ; i<count ; i++) {
5790aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                const sp<LayerBase>& layer(previousLayers[i]);
5800aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                if (currentLayers.indexOf( layer ) < 0) {
5810aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                    // this layer is not visible anymore
5825d7126b625c8c4a7b945e8c247b63abff7bc13b6Mathias Agopian                    mDirtyRegionRemovedLayer.orSelf(layer->visibleRegionScreen);
5830aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                }
5840aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            }
585edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
586edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
587edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
588edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    commitTransaction();
589edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
590edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
591edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::computeVisibleRegions(
5921bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian    const LayerVector& currentLayers, Region& dirtyRegion, Region& opaqueRegion)
593edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
594841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
595841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
596edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(graphicPlane(0));
597edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Transform& planeTransform(plane.transform());
598ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian    const DisplayHardware& hw(plane.displayHardware());
599ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian    const Region screenRegion(hw.bounds());
600edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
601edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveOpaqueLayers;
602edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveCoveredLayers;
603edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region dirty;
604edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
605edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    bool secureFrameBuffer = false;
606edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
607edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t i = currentLayers.size();
608edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    while (i--) {
609076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        const sp<LayerBase>& layer = currentLayers[i];
610edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->validateVisibility(planeTransform);
611edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
612edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // start with the whole surface at its current location
613970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian        const Layer::State& s(layer->drawingState());
614edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
615ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
616ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * opaqueRegion: area of a surface that is fully opaque.
617ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
618edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region opaqueRegion;
619ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
620ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
621ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visibleRegion: area of a surface that is visible on screen
622ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * and not fully transparent. This is essentially the layer's
623ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * footprint minus the opaque regions above it.
624ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * Areas covered by a translucent surface are considered visible.
625ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
626edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region visibleRegion;
627ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
628ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
629ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * coveredRegion: area of a surface that is covered by all
630ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visible regions above it (which includes the translucent areas).
631ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
632edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region coveredRegion;
633ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
634ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
635ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // handle hidden surfaces by setting the visible region to empty
63699ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten        if (CC_LIKELY(!(s.flags & ISurfaceComposer::eLayerHidden) && s.alpha)) {
637a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            const bool translucent = !layer->isOpaque();
638970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian            const Rect bounds(layer->visibleBounds());
639edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            visibleRegion.set(bounds);
640ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            visibleRegion.andSelf(screenRegion);
641ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            if (!visibleRegion.isEmpty()) {
642ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // Remove the transparent area from the visible region
643ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (translucent) {
644ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    visibleRegion.subtractSelf(layer->transparentRegionScreen);
645ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
646edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
647ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // compute the opaque region
648ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                const int32_t layerOrientation = layer->getOrientation();
649ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (s.alpha==255 && !translucent &&
650ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                        ((layerOrientation & Transform::ROT_INVALID) == false)) {
651ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    // the opaque region is the layer's footprint
652ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    opaqueRegion = visibleRegion;
653ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
654edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
655edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
656edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
657ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Clip the covered region to the visible region
658ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        coveredRegion = aboveCoveredLayers.intersect(visibleRegion);
659ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
660ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveCoveredLayers for next (lower) layer
661ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        aboveCoveredLayers.orSelf(visibleRegion);
662ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
663edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // subtract the opaque region covered by the layers above us
664edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        visibleRegion.subtractSelf(aboveOpaqueLayers);
665edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
666edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // compute this layer's dirty region
667edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (layer->contentDirty) {
668edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // we need to invalidate the whole region
669edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dirty = visibleRegion;
670edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // as well, as the old visible region
671edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dirty.orSelf(layer->visibleRegionScreen);
672edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->contentDirty = false;
673edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
674a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian            /* compute the exposed region:
675ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   the exposed region consists of two components:
676ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   1) what's VISIBLE now and was COVERED before
677ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   2) what's EXPOSED now less what was EXPOSED before
678ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
679ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * note that (1) is conservative, we start with the whole
680ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * visible region but only keep what used to be covered by
681ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * something -- which mean it may have been exposed.
682ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
683ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * (2) handles areas that were not covered by anything but got
684ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * exposed because of a resize.
685a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian             */
686ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region newExposed = visibleRegion - coveredRegion;
687ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldVisibleRegion = layer->visibleRegionScreen;
688ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldCoveredRegion = layer->coveredRegionScreen;
689ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldExposed = oldVisibleRegion - oldCoveredRegion;
690ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed);
691edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
692edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirty.subtractSelf(aboveOpaqueLayers);
693edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
694edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // accumulate to the screen dirty region
695edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirtyRegion.orSelf(dirty);
696edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
697ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveOpaqueLayers for next (lower) layer
698edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        aboveOpaqueLayers.orSelf(opaqueRegion);
6998b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
700edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // Store the visible region is screen space
701edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setVisibleRegion(visibleRegion);
702edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setCoveredRegion(coveredRegion);
703edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
704970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian        // If a secure layer is partially visible, lock-down the screen!
705edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (layer->isSecure() && !visibleRegion.isEmpty()) {
706edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            secureFrameBuffer = true;
707edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
708edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
709edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
710970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian    // invalidate the areas where a layer was removed
711970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian    dirtyRegion.orSelf(mDirtyRegionRemovedLayer);
712970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian    mDirtyRegionRemovedLayer.clear();
713970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian
714edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mSecureFrameBuffer = secureFrameBuffer;
715edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    opaqueRegion = aboveOpaqueLayers;
716edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
717edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
718edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
719edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::commitTransaction()
720edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
7212f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall    if (!mLayersPendingRemoval.isEmpty()) {
7222f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall        // Notify removed layers now that they can't be drawn from
7232f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall        for (size_t i = 0; i < mLayersPendingRemoval.size(); i++) {
7242f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall            mLayersPendingRemoval[i]->onRemoved();
7252f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall        }
7262f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall        mLayersPendingRemoval.clear();
7272f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall    }
7282f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall
729edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDrawingState = mCurrentState;
73028378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    mTransationPending = false;
731cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mTransactionCV.broadcast();
732edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
733edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
734edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handlePageFlip()
735edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
7361c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
73799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    const DisplayHardware& hw = graphicPlane(0).displayHardware();
73899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    const Region screenRegion(hw.bounds());
73999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
7401bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian    const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
74199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    const bool visibleRegions = lockPageFlip(currentLayers);
742edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
74399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        if (visibleRegions || mVisibleRegionsDirty) {
744edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            Region opaqueRegion;
745edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            computeVisibleRegions(currentLayers, mDirtyRegion, opaqueRegion);
7464da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
7474da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            /*
7484da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian             *  rebuild the visible layer list
7494da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian             */
7501bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian            const size_t count = currentLayers.size();
7514da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            mVisibleLayersSortedByZ.clear();
7524da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            mVisibleLayersSortedByZ.setCapacity(count);
7534da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            for (size_t i=0 ; i<count ; i++) {
7544da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian                if (!currentLayers[i]->visibleRegionScreen.isEmpty())
7554da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian                    mVisibleLayersSortedByZ.add(currentLayers[i]);
7564da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            }
7574da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
758edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mWormholeRegion = screenRegion.subtract(opaqueRegion);
759edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = false;
760ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian            invalidateHwcGeometry();
761edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
762edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
763edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    unlockPageFlip(currentLayers);
7640dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian
7650dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    mDirtyRegion.orSelf(getAndClearInvalidateRegion());
766edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDirtyRegion.andSelf(screenRegion);
767edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
768edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
769ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopianvoid SurfaceFlinger::invalidateHwcGeometry()
770ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian{
771ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian    mHwWorkListDirty = true;
772ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian}
773ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian
774edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool SurfaceFlinger::lockPageFlip(const LayerVector& currentLayers)
775edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
776edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    bool recomputeVisibleRegions = false;
777edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t count = currentLayers.size();
778076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBase> const* layers = currentLayers.array();
779edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (size_t i=0 ; i<count ; i++) {
780b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
781edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->lockPageFlip(recomputeVisibleRegions);
782edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
783edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return recomputeVisibleRegions;
784edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
785edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
786edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::unlockPageFlip(const LayerVector& currentLayers)
787edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
788edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(graphicPlane(0));
789edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Transform& planeTransform(plane.transform());
79099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    const 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->unlockPageFlip(planeTransform, mDirtyRegion);
795edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
796edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
797edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
79899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::handleRefresh()
79999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
80099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    bool needInvalidate = false;
80199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
80299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    const size_t count = currentLayers.size();
80399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
80499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
80599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        if (layer->onPreComposition()) {
80699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            needInvalidate = true;
80799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        }
80899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    }
80999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    if (needInvalidate) {
81099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        signalLayerUpdate();
81199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    }
81299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
81399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
81499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
815a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopianvoid SurfaceFlinger::handleWorkList()
816a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian{
817a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    mHwWorkListDirty = false;
818a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    HWComposer& hwc(graphicPlane(0).displayHardware().getHwComposer());
819a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    if (hwc.initCheck() == NO_ERROR) {
820a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        const Vector< sp<LayerBase> >& currentLayers(mVisibleLayersSortedByZ);
821a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        const size_t count = currentLayers.size();
822a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        hwc.createWorkList(count);
8233e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian
8243e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian        HWComposer::LayerListIterator cur = hwc.begin();
8253e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian        const HWComposer::LayerListIterator end = hwc.end();
8263e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian        for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
8273e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian            currentLayers[i]->setGeometry(*cur);
82853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian            if (mDebugDisableHWC || mDebugRegion) {
8293e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian                cur->setSkip(true);
83073d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian            }
831a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        }
832a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
833a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian}
834b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian
835edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleRepaint()
836edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
837841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
838841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
839b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // compute the invalid region
8400656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian    mSwapRegion.orSelf(mDirtyRegion);
841edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
84299ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten    if (CC_UNLIKELY(mDebugRegion)) {
843edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        debugFlashRegions();
844edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
845edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
846b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // set the frame buffer
847b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
848b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    glMatrixMode(GL_MODELVIEW);
849b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    glLoadIdentity();
850edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
851edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t flags = hw.getFlags();
852a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian    if (flags & DisplayHardware::SWAP_RECTANGLE) {
85329d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // we can redraw only what's dirty, but since SWAP_RECTANGLE only
85429d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // takes a rectangle, we must make sure to update that whole
85529d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // rectangle in that case
856a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        mDirtyRegion.set(mSwapRegion.bounds());
857edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
85895a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian        if (flags & DisplayHardware::PARTIAL_UPDATES) {
85929d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // We need to redraw the rectangle that will be updated
860df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian            // (pushed to the framebuffer).
86195a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian            // This is needed because PARTIAL_UPDATES only takes one
86229d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // rectangle instead of a region (see DisplayHardware::flip())
8630656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian            mDirtyRegion.set(mSwapRegion.bounds());
864edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
86529d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // we need to redraw everything (the whole screen)
866edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mDirtyRegion.set(hw.bounds());
8670656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian            mSwapRegion = mDirtyRegion;
868edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
869edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
870edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
871a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian    setupHardwareComposer();
872edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    composeSurfaces(mDirtyRegion);
873edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
8749c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    // update the swap region and clear the dirty region
8759c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    mSwapRegion.orSelf(mDirtyRegion);
876edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDirtyRegion.clear();
877edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
878edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
879a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopianvoid SurfaceFlinger::setupHardwareComposer()
880edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
881f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
882f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    HWComposer& hwc(hw.getHwComposer());
8833e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian
8843e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    HWComposer::LayerListIterator cur = hwc.begin();
8853e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    const HWComposer::LayerListIterator end = hwc.end();
8863e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    if (cur == end) {
8879c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        return;
888edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
889a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
8904da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian    const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
89145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    size_t count = layers.size();
892a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
893e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block    ALOGE_IF(hwc.getNumLayers() != count,
89445721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            "HAL number of layers (%d) doesn't match surfaceflinger (%d)",
89545721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            hwc.getNumLayers(), count);
896a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
89745721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    // just to be extra-safe, use the smallest count
89824925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling    if (hwc.initCheck() == NO_ERROR) {
89924925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling        count = count < hwc.getNumLayers() ? count : hwc.getNumLayers();
90024925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling    }
901a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
90245721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    /*
90345721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     *  update the per-frame h/w composer data for each layer
90445721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     *  and build the transparent region of the FB
90545721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     */
9063e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
907f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
9083e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian        layer->setPerFrameData(*cur);
909f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    }
910f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    status_t err = hwc.prepare();
911e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block    ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
912f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian}
913f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian
914f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopianvoid SurfaceFlinger::composeSurfaces(const Region& dirty)
915f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian{
916cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
917cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian    HWComposer& hwc(hw.getHwComposer());
9183e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    HWComposer::LayerListIterator cur = hwc.begin();
9193e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    const HWComposer::LayerListIterator end = hwc.end();
920cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian
921cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian    const size_t fbLayerCount = hwc.getLayerCount(HWC_FRAMEBUFFER);
9223e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    if (cur==end || fbLayerCount) {
923a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        // Never touch the framebuffer if we don't have any framebuffer layers
92445721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian
925b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian        if (hwc.getLayerCount(HWC_OVERLAY)) {
926b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // when using overlays, we assume a fully transparent framebuffer
927b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // NOTE: we could reduce how much we need to clear, for instance
928b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // remove where there are opaque FB layers. however, on some
929b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // GPUs doing a "clean slate" glClear might be more efficient.
930b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // We'll revisit later if needed.
931b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            glClearColor(0, 0, 0, 0);
932b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            glClear(GL_COLOR_BUFFER_BIT);
933b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian        } else {
934b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // screen is already cleared here
935b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            if (!mWormholeRegion.isEmpty()) {
936b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                // can happen with SurfaceView
937b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                drawWormhole();
938b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            }
939a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        }
9404b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian
941a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        /*
942a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian         * and then, render the layers targeted at the framebuffer
943a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian         */
9444b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian
945a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
946a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        const size_t count = layers.size();
9473e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian        for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
948a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian            const sp<LayerBase>& layer(layers[i]);
949a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian            const Region clip(dirty.intersect(layer->visibleRegionScreen));
950a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian            if (!clip.isEmpty()) {
9513e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian                if (cur->getCompositionType() == HWC_OVERLAY) {
9523e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian                    if (i && (cur->getHints() & HWC_HINT_CLEAR_FB)
953a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                            && layer->isOpaque()) {
954b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                        // never clear the very first layer since we're
955b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                        // guaranteed the FB is already cleared
956a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                        layer->clearWithOpenGL(clip);
957a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                    }
958a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                    continue;
959a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                }
960a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                // render the layer
961a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                layer->draw(clip);
9624b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian            }
9634b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian        }
9644b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian    }
965edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
966edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
967edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::debugFlashRegions()
968edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
9690a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
9700a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    const uint32_t flags = hw.getFlags();
97153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian    const int32_t height = hw.getHeight();
9720656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian    if (mSwapRegion.isEmpty()) {
97353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian        return;
97453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian    }
9750a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
976a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian    if (!(flags & DisplayHardware::SWAP_RECTANGLE)) {
9770a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        const Region repaint((flags & DisplayHardware::PARTIAL_UPDATES) ?
9780a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian                mDirtyRegion.bounds() : hw.bounds());
9790a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        composeSurfaces(repaint);
9800a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    }
9810a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
982c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_EXTERNAL_OES);
983c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_2D);
984edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_BLEND);
985edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
9860926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    static int toggle = 0;
9870926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    toggle = 1 - toggle;
9880926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    if (toggle) {
9890a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        glColor4f(1, 0, 1, 1);
9900926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    } else {
9910a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        glColor4f(1, 1, 0, 1);
9920926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    }
993edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
99420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    Region::const_iterator it = mDirtyRegion.begin();
99520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    Region::const_iterator const end = mDirtyRegion.end();
99620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    while (it != end) {
99720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        const Rect& r = *it++;
998edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLfloat vertices[][2] = {
99953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.left,  height - r.top },
100053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.left,  height - r.bottom },
100153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.right, height - r.bottom },
100253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.right, height - r.top }
1003edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        };
1004edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glVertexPointer(2, GL_FLOAT, 0, vertices);
1005edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1006edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
10070a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
10080656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian    hw.flip(mSwapRegion);
1009edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1010edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mDebugRegion > 1)
10110a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        usleep(mDebugRegion * 1000);
1012edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1013edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1014edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::drawWormhole() const
1015edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1016edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Region region(mWormholeRegion.intersect(mDirtyRegion));
1017edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (region.isEmpty())
1018edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1019edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1020f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    glDisable(GL_TEXTURE_EXTERNAL_OES);
1021b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian    glDisable(GL_TEXTURE_2D);
1022f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    glDisable(GL_BLEND);
1023b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian    glColor4f(0,0,0,0);
1024f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian
1025f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    GLfloat vertices[4][2];
1026f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    glVertexPointer(2, GL_FLOAT, 0, vertices);
1027f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    Region::const_iterator it = region.begin();
1028f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    Region::const_iterator const end = region.end();
1029f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    while (it != end) {
1030f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        const Rect& r = *it++;
1031f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[0][0] = r.left;
1032f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[0][1] = r.top;
1033f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[1][0] = r.right;
1034f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[1][1] = r.top;
1035f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[2][0] = r.right;
1036f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[2][1] = r.bottom;
1037f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[3][0] = r.left;
1038f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[3][1] = r.bottom;
1039f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1040f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    }
1041edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1042edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1043076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::addLayer(const sp<LayerBase>& layer)
1044edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1045edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
1046edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    addLayer_l(layer);
1047edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
1048edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1049edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1050edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1051076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::addLayer_l(const sp<LayerBase>& layer)
1052edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1053f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian    ssize_t i = mCurrentState.layersSortedByZ.add(layer);
10541b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    return (i < 0) ? status_t(i) : status_t(NO_ERROR);
10551b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian}
10561b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
105796f0819f81293076e652792794a961543e6750d7Mathias Agopianssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
105896f0819f81293076e652792794a961543e6750d7Mathias Agopian        const sp<LayerBaseClient>& lbc)
10591b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
106096f0819f81293076e652792794a961543e6750d7Mathias Agopian    // attach this layer to the client
10614f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    size_t name = client->attachLayer(lbc);
10624f113740180b6512b43723c4728f262882dc9b45Mathias Agopian
10634f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    Mutex::Autolock _l(mStateLock);
106496f0819f81293076e652792794a961543e6750d7Mathias Agopian
106596f0819f81293076e652792794a961543e6750d7Mathias Agopian    // add this layer to the current state list
106696f0819f81293076e652792794a961543e6750d7Mathias Agopian    addLayer_l(lbc);
106796f0819f81293076e652792794a961543e6750d7Mathias Agopian
10684f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    return ssize_t(name);
106996f0819f81293076e652792794a961543e6750d7Mathias Agopian}
107096f0819f81293076e652792794a961543e6750d7Mathias Agopian
107196f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer)
107296f0819f81293076e652792794a961543e6750d7Mathias Agopian{
107396f0819f81293076e652792794a961543e6750d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
107496f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = purgatorizeLayer_l(layer);
107596f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR)
107696f0819f81293076e652792794a961543e6750d7Mathias Agopian        setTransactionFlags(eTransactionNeeded);
107796f0819f81293076e652792794a961543e6750d7Mathias Agopian    return err;
1078edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1079edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1080076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase)
1081edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1082b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<LayerBaseClient> lbc(layerBase->getLayerBaseClient());
1083b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (lbc != 0) {
10840d1561275e80073807ac04728951782d943f8882Mathias Agopian        mLayerMap.removeItem( lbc->getSurfaceBinder() );
1085b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    }
1086edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase);
1087edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (index >= 0) {
1088076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved = true;
1089edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
1090edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
10913d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    return status_t(index);
1092edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1093edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
10949a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase)
10959a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
109676cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    // First add the layer to the purgatory list, which makes sure it won't
109776cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    // go away, then remove it from the main list (through a transaction).
10989a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    ssize_t err = removeLayer_l(layerBase);
109976cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    if (err >= 0) {
110076cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian        mLayerPurgatory.add(layerBase);
110176cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    }
11028c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian
11032f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall    mLayersPendingRemoval.push(layerBase);
11040b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian
11053d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // it's possible that we don't find a layer, because it might
11063d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // have been destroyed already -- this is not technically an error
110796f0819f81293076e652792794a961543e6750d7Mathias Agopian    // from the user because there is a race between Client::destroySurface(),
110896f0819f81293076e652792794a961543e6750d7Mathias Agopian    // ~Client() and ~ISurface().
11099a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err;
11109a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
11119a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
111296f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::invalidateLayerVisibility(const sp<LayerBase>& layer)
1113edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
111496f0819f81293076e652792794a961543e6750d7Mathias Agopian    layer->forceVisibilityTransaction();
111596f0819f81293076e652792794a961543e6750d7Mathias Agopian    setTransactionFlags(eTraversalNeeded);
111696f0819f81293076e652792794a961543e6750d7Mathias Agopian    return NO_ERROR;
1117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1119dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopianuint32_t SurfaceFlinger::peekTransactionFlags(uint32_t flags)
1120dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian{
1121dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian    return android_atomic_release_load(&mTransactionFlags);
1122dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian}
1123dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian
1124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags)
1125edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1126edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return android_atomic_and(~flags, &mTransactionFlags) & flags;
1127edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1129bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags)
1130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t old = android_atomic_or(flags, &mTransactionFlags);
1132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((old & flags)==0) { // wake the server up
113399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        signalTransaction();
1134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return old;
1136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1139b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennisvoid SurfaceFlinger::setTransactionState(const Vector<ComposerState>& state,
114028378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        int orientation, uint32_t flags) {
1141698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
1142cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
114328378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    uint32_t transactionFlags = 0;
1144b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis    if (mCurrentState.orientation != orientation) {
1145b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis        if (uint32_t(orientation)<=eOrientation270 || orientation==42) {
1146b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis            mCurrentState.orientation = orientation;
114728378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis            transactionFlags |= eTransactionNeeded;
1148b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis        } else if (orientation != eOrientationUnchanged) {
114932397c1cd3327905173b36baa6fd1c579bc328ffSteve Block            ALOGW("setTransactionState: ignoring unrecognized orientation: %d",
1150b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis                    orientation);
1151b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis        }
1152b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis    }
1153b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis
1154698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    const size_t count = state.size();
1155698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
1156698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const ComposerState& s(state[i]);
1157698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        sp<Client> client( static_cast<Client *>(s.client.get()) );
115828378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        transactionFlags |= setClientStateLocked(client, s.state);
1159698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    }
1160386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian
116128378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    if (transactionFlags) {
1162386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // this triggers the transaction
116328378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        setTransactionFlags(transactionFlags);
1164698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian
1165386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // if this is a synchronous transaction, wait for it to take effect
1166386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // before returning.
1167386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        if (flags & eSynchronous) {
1168386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            mTransationPending = true;
1169386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        }
1170386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        while (mTransationPending) {
1171386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
1172386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            if (CC_UNLIKELY(err != NO_ERROR)) {
1173386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                // just in case something goes wrong in SF, return to the
1174386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                // called after a few seconds.
117532397c1cd3327905173b36baa6fd1c579bc328ffSteve Block                ALOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!");
1176386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                mTransationPending = false;
1177386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                break;
1178386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            }
1179cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        }
1180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
11830ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopiansp<ISurface> SurfaceFlinger::createSurface(
11840ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        ISurfaceComposerClient::surface_data_t* params,
11850ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const String8& name,
11860ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const sp<Client>& client,
1187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        DisplayID d, uint32_t w, uint32_t h, PixelFormat format,
1188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t flags)
1189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1190076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBaseClient> layer;
1191a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    sp<ISurface> surfaceHandle;
11926e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian
11936e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    if (int32_t(w|h) < 0) {
1194e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE("createSurface() failed, w or h is negative (w=%d, h=%d)",
11956e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian                int(w), int(h));
11966e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian        return surfaceHandle;
11976e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    }
11988b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
1199ff615cc7a1cceedd705b0623b058c54669b29596Mathias Agopian    //ALOGD("createSurface for (%d x %d), name=%s", w, h, name.string());
1200b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<Layer> normalLayer;
1201edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (flags & eFXSurfaceMask) {
1202edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceNormal:
1203a5529c8778c2f407f482fc12165aeb76c0f505c2Mathias Agopian            normalLayer = createNormalSurface(client, d, w, h, flags, format);
1204a5529c8778c2f407f482fc12165aeb76c0f505c2Mathias Agopian            layer = normalLayer;
1205edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
1206edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceBlur:
12071293a8eb567fd63c072a6970fa9dcf37d076059fMathias Agopian            // for now we treat Blur as Dim, until we can implement it
12081293a8eb567fd63c072a6970fa9dcf37d076059fMathias Agopian            // efficiently.
1209edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceDim:
121096f0819f81293076e652792794a961543e6750d7Mathias Agopian            layer = createDimSurface(client, d, w, h, flags);
1211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
1212118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        case eFXSurfaceScreenshot:
1213118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian            layer = createScreenshotSurface(client, d, w, h, flags);
1214118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian            break;
1215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1217076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (layer != 0) {
121896f0819f81293076e652792794a961543e6750d7Mathias Agopian        layer->initStates(w, h, flags);
1219285dbde2e0cd0057be070ded3be8f5f453147edcMathias Agopian        layer->setName(name);
122096f0819f81293076e652792794a961543e6750d7Mathias Agopian        ssize_t token = addClientLayer(client, layer);
1221b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        surfaceHandle = layer->getSurface();
12238b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber        if (surfaceHandle != 0) {
122496f0819f81293076e652792794a961543e6750d7Mathias Agopian            params->token = token;
1225a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            params->identity = layer->getIdentity();
1226b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            if (normalLayer != 0) {
1227b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian                Mutex::Autolock _l(mStateLock);
1228a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                mLayerMap.add(layer->getSurfaceBinder(), normalLayer);
1229b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            }
12301c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        }
1231b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
123296f0819f81293076e652792794a961543e6750d7Mathias Agopian        setTransactionFlags(eTransactionNeeded);
1233edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return surfaceHandle;
1236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1238b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<Layer> SurfaceFlinger::createNormalSurface(
1239f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        const sp<Client>& client, DisplayID display,
124096f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags,
12411c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        PixelFormat& format)
1242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize the surfaces
1244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (format) { // TODO: take h/w into account
1245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSPARENT:
1246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSLUCENT:
1247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        format = PIXEL_FORMAT_RGBA_8888;
1248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_OPAQUE:
1250a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888
1251a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian        format = PIXEL_FORMAT_RGB_565;
1252a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#else
12538f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian        format = PIXEL_FORMAT_RGBX_8888;
1254a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif
1255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1258a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888
1259a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian    if (format == PIXEL_FORMAT_RGBX_8888)
1260a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian        format = PIXEL_FORMAT_RGBA_8888;
1261a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif
1262a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian
126396f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<Layer> layer = new Layer(this, display, client);
1264f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian    status_t err = layer->setBuffers(w, h, format, flags);
126599ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten    if (CC_LIKELY(err != NO_ERROR)) {
1266e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE("createNormalSurfaceLocked() failed (%s)", strerror(-err));
1267076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        layer.clear();
1268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1269edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1272b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<LayerDim> SurfaceFlinger::createDimSurface(
1273f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        const sp<Client>& client, DisplayID display,
127496f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags)
1275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
127696f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<LayerDim> layer = new LayerDim(this, display, client);
1277118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    return layer;
1278118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
1279118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
1280118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopiansp<LayerScreenshot> SurfaceFlinger::createScreenshotSurface(
1281118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        const sp<Client>& client, DisplayID display,
1282118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags)
1283118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{
1284118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    sp<LayerScreenshot> layer = new LayerScreenshot(this, display, client);
1285edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1286edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1287edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
128896f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeSurface(const sp<Client>& client, SurfaceID sid)
12899a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
12909a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    /*
12919a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     * called by the window manager, when a surface should be marked for
12929a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     * destruction.
12938b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber     *
12940aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * The surface is removed from the current and drawing lists, but placed
12950aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * in the purgatory queue, so it's not destroyed right-away (we need
12960aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * to wait for all client's references to go away first).
12979a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     */
12989a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
129948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    status_t err = NAME_NOT_FOUND;
13000aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian    Mutex::Autolock _l(mStateLock);
130196f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<LayerBaseClient> layer = client->getLayerUser(sid);
1302b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam
130348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    if (layer != 0) {
130448d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        err = purgatorizeLayer_l(layer);
130548d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        if (err == NO_ERROR) {
130648d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian            setTransactionFlags(eTransactionNeeded);
130748d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        }
13089a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    }
13099a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return err;
13109a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
13119a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
1312ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopianstatus_t SurfaceFlinger::destroySurface(const wp<LayerBaseClient>& layer)
1313edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1314759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian    // called by ~ISurface() when all references are gone
1315ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    status_t err = NO_ERROR;
1316ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    sp<LayerBaseClient> l(layer.promote());
1317ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    if (l != NULL) {
1318ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        Mutex::Autolock _l(mStateLock);
1319ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        err = removeLayer_l(l);
1320ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        if (err == NAME_NOT_FOUND) {
1321ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // The surface wasn't in the current list, which means it was
1322ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // removed already, which means it is in the purgatory,
1323ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // and need to be removed from there.
1324ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            ssize_t idx = mLayerPurgatory.remove(l);
1325e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block            ALOGE_IF(idx < 0,
1326ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian                    "layer=%p is not in the purgatory list", l.get());
1327f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        }
1328e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE_IF(err<0 && err != NAME_NOT_FOUND,
1329ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian                "error removing layer=%p (%s)", l.get(), strerror(-err));
1330ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    }
1331ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    return err;
1332edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1334698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopianuint32_t SurfaceFlinger::setClientStateLocked(
133596f0819f81293076e652792794a961543e6750d7Mathias Agopian        const sp<Client>& client,
1336698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const layer_state_t& s)
1337edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1338edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t flags = 0;
1339698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    sp<LayerBaseClient> layer(client->getLayerUser(s.surface));
1340698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    if (layer != 0) {
1341698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const uint32_t what = s.what;
1342698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & ePositionChanged) {
1343698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setPosition(s.x, s.y))
1344698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1345698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1346698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eLayerChanged) {
1347698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
1348698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setLayer(s.z)) {
1349698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                mCurrentState.layersSortedByZ.removeAt(idx);
1350698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                mCurrentState.layersSortedByZ.add(layer);
1351698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                // we need traversal (state changed)
1352698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                // AND transaction (list changed)
1353698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTransactionNeeded|eTraversalNeeded;
1354edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1355698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1356698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eSizeChanged) {
1357698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setSize(s.w, s.h)) {
1358698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1359edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1360edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1361698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eAlphaChanged) {
1362698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f)))
1363698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1364698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1365698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eMatrixChanged) {
1366698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setMatrix(s.matrix))
1367698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1368698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1369698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eTransparentRegionChanged) {
1370698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setTransparentRegionHint(s.transparentRegion))
1371698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1372698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1373698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eVisibilityChanged) {
1374698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setFlags(s.flags, s.mask))
1375698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1376698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1377f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        if (what & eCropChanged) {
1378f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis            if (layer->setCrop(s.crop))
1379f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis                flags |= eTraversalNeeded;
1380f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        }
1381edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1382698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    return flags;
1383edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1384edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1385b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// ---------------------------------------------------------------------------
1386b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
1387b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopianvoid SurfaceFlinger::onScreenAcquired() {
13888e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross    ALOGD("Screen about to return, flinger = %p", this);
1389b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
1390b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    hw.acquireScreen();
139122ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian    mEventThread->onScreenAcquired();
1392b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    // this is a temporary work-around, eventually this should be called
1393b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    // by the power-manager
1394b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    SurfaceFlinger::turnElectronBeamOn(mElectronBeamAnimationMode);
139522ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian    // from this point on, SF will process updates again
13968acce2046ac7086c3dcfb1fc7c9c39f31de48694Mathias Agopian    repaintEverything();
1397edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1398edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1399b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopianvoid SurfaceFlinger::onScreenReleased() {
14008e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross    ALOGD("About to give-up screen, flinger = %p", this);
1401b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
1402b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    if (hw.isScreenAcquired()) {
140322ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian        mEventThread->onScreenReleased();
1404b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        hw.releaseScreen();
1405b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        // from this point on, SF will stop drawing
1406b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    }
1407b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian}
1408b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
14098e533069e5721e55cb9768e140e16546c3a4a8b6Colin Crossvoid SurfaceFlinger::unblank() {
1410b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    class MessageScreenAcquired : public MessageBase {
1411b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        SurfaceFlinger* flinger;
1412b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    public:
1413b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        MessageScreenAcquired(SurfaceFlinger* flinger) : flinger(flinger) { }
1414b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        virtual bool handler() {
1415b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            flinger->onScreenAcquired();
1416b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            return true;
1417b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        }
1418b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    };
1419b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    sp<MessageBase> msg = new MessageScreenAcquired(this);
1420b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    postMessageSync(msg);
1421edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1422edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
14238e533069e5721e55cb9768e140e16546c3a4a8b6Colin Crossvoid SurfaceFlinger::blank() {
1424b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    class MessageScreenReleased : public MessageBase {
1425b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        SurfaceFlinger* flinger;
1426b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    public:
1427b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        MessageScreenReleased(SurfaceFlinger* flinger) : flinger(flinger) { }
1428b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        virtual bool handler() {
1429b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            flinger->onScreenReleased();
1430b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            return true;
1431b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        }
1432b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    };
1433b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    sp<MessageBase> msg = new MessageScreenReleased(this);
1434b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    postMessageSync(msg);
1435b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian}
1436b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
1437b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// ---------------------------------------------------------------------------
1438b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
1439edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
1440edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
14411d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling    const size_t SIZE = 4096;
1442edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char buffer[SIZE];
1443edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    String8 result;
144499b49840d309727678b77403d6cc9f920111623fMathias Agopian
144599b49840d309727678b77403d6cc9f920111623fMathias Agopian    if (!PermissionCache::checkCallingPermission(sDump)) {
1446edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        snprintf(buffer, SIZE, "Permission Denial: "
1447edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                "can't dump SurfaceFlinger from pid=%d, uid=%d\n",
1448edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                IPCThreadState::self()->getCallingPid(),
1449edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                IPCThreadState::self()->getCallingUid());
1450edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        result.append(buffer);
1451edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
14529795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // Try to get the main lock, but don't insist if we can't
14539795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // (this would indicate SF is stuck, but we want to be able to
14549795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // print something in dumpsys).
14559795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        int retry = 3;
14569795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        while (mStateLock.tryLock()<0 && --retry>=0) {
14579795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            usleep(1000000);
14589795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
14599795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const bool locked(retry >= 0);
14609795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (!locked) {
14618b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber            snprintf(buffer, SIZE,
14629795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "SurfaceFlinger appears to be unresponsive, "
14639795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "dumping anyways (no locks held)\n");
14649795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            result.append(buffer);
14659795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
14669795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
146782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        bool dumpAll = true;
146882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        size_t index = 0;
146925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        size_t numArgs = args.size();
147025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        if (numArgs) {
147125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
147225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--list"))) {
147325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                index++;
147425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                listLayersLocked(args, index, result, buffer, SIZE);
147535aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
147625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            }
147725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
147825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
147925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--latency"))) {
148082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                index++;
148182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                dumpStatsLocked(args, index, result, buffer, SIZE);
148235aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
148382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            }
148425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
148525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
148625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--latency-clear"))) {
148725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                index++;
148825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                clearStatsLocked(args, index, result, buffer, SIZE);
148935aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
149025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            }
1491edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
14921b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
149382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (dumpAll) {
149482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            dumpAllLocked(result, buffer, SIZE);
149582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
149648b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
149782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (locked) {
149882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mStateLock.unlock();
149948b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        }
150082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
150182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    write(fd, result.string(), result.size());
150282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    return NO_ERROR;
150382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
150448b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
150525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::listLayersLocked(const Vector<String16>& args, size_t& index,
150625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        String8& result, char* buffer, size_t SIZE) const
150725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
150825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
150925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const size_t count = currentLayers.size();
151025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
151125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
151225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        snprintf(buffer, SIZE, "%s\n", layer->getName().string());
151325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        result.append(buffer);
151425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
151525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
151625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
151782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index,
151882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        String8& result, char* buffer, size_t SIZE) const
151982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
152082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    String8 name;
152182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    if (index < args.size()) {
152282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        name = String8(args[index]);
152382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        index++;
152482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
152548b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
152682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
152782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const size_t count = currentLayers.size();
152882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    for (size_t i=0 ; i<count ; i++) {
152982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
153082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (name.isEmpty()) {
153182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            snprintf(buffer, SIZE, "%s\n", layer->getName().string());
153282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            result.append(buffer);
153382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
153482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (name.isEmpty() || (name == layer->getName())) {
153582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            layer->dumpStats(result, buffer, SIZE);
153682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
153782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
153882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
1539ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian
154025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& index,
154125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        String8& result, char* buffer, size_t SIZE) const
154225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
154325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    String8 name;
154425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    if (index < args.size()) {
154525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        name = String8(args[index]);
154625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        index++;
154725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
154825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
154925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
155025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const size_t count = currentLayers.size();
155125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
155225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
155325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        if (name.isEmpty() || (name == layer->getName())) {
155425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            layer->clearStats();
155525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        }
155625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
155725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
155825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
155982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpAllLocked(
156082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        String8& result, char* buffer, size_t SIZE) const
156182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
156282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    // figure out if we're stuck somewhere
156382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t now = systemTime();
156482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t inSwapBuffers(mDebugInSwapBuffers);
156582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t inTransaction(mDebugInTransaction);
156682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0;
156782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0;
1568bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
156982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
157082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump the visible layer list
157182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
157282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
157382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const size_t count = currentLayers.size();
157482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "Visible layers (count = %d)\n", count);
157582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
157682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    for (size_t i=0 ; i<count ; i++) {
157782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
157882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        layer->dump(result, buffer, SIZE);
157982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
1580bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
158182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
158282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump the layers in the purgatory
158382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
1584ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian
158582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const size_t purgatorySize = mLayerPurgatory.size();
158682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "Purgatory state (%d entries)\n", purgatorySize);
158782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
158882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    for (size_t i=0 ; i<purgatorySize ; i++) {
158982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
159082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        layer->shortDump(result, buffer, SIZE);
159182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
15921b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
159382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
159482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump SurfaceFlinger global state
159582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
15961b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
159782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "SurfaceFlinger global state:\n");
159882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
15991b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
160082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const GLExtensions& extensions(GLExtensions::getInstance());
160182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "GLES: %s, %s, %s\n",
160282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            extensions.getVendor(),
160382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            extensions.getRenderer(),
160482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            extensions.getVersion());
160582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
1606d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
160782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "EGL : %s\n",
160882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            eglQueryString(graphicPlane(0).getEGLDisplay(),
160982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                    EGL_VERSION_HW_ANDROID));
161082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
161173d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian
161282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "EXTS: %s\n", extensions.getExtension());
161382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
16149795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
161582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    mWormholeRegion.dump(result, "WormholeRegion");
161682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
161782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE,
161882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  orientation=%d, canDraw=%d\n",
161982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mCurrentState.orientation, hw.canDraw());
162082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
162182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE,
162282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  last eglSwapBuffers() time: %f us\n"
162382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  last transaction time     : %f us\n"
1624c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian            "  transaction-flags         : %08x\n"
162582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  refresh-rate              : %f fps\n"
162682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  x-dpi                     : %f\n"
1627b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian            "  y-dpi                     : %f\n"
1628b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian            "  density                   : %f\n",
162982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mLastSwapBufferTime/1000.0,
163082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mLastTransactionTime/1000.0,
1631c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian            mTransactionFlags,
163282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            hw.getRefreshRate(),
163382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            hw.getDpiX(),
1634b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian            hw.getDpiY(),
1635b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian            hw.getDensity());
163682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
163782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
163882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "  eglSwapBuffers time: %f us\n",
163982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            inSwapBuffersDuration/1000.0);
164082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
164182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
164282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "  transaction time: %f us\n",
164382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            inTransactionDuration/1000.0);
164482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
164582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
164682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
164782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * VSYNC state
164882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
164982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    mEventThread->dump(result, buffer, SIZE);
165082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
165182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
165282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump HWComposer state
165382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
165482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    HWComposer& hwc(hw.getHwComposer());
165582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "h/w composer state:\n");
165682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
165782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "  h/w composer %s and %s\n",
165882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            hwc.initCheck()==NO_ERROR ? "present" : "not present",
165982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                    (mDebugDisableHWC || mDebugRegion) ? "disabled" : "enabled");
166082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
166182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    hwc.dump(result, buffer, SIZE, mVisibleLayersSortedByZ);
166282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
166382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
166482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump gralloc state
166582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
166682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
166782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    alloc.dump(result);
166882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    hw.dump(result);
1669edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1670edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1671edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::onTransact(
1672edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
1673edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1674edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (code) {
1675edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case CREATE_CONNECTION:
1676698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        case SET_TRANSACTION_STATE:
1677edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case SET_ORIENTATION:
1678edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case BOOT_FINISHED:
167959119e658a12279e8fff508f8773843de2d90917Mathias Agopian        case TURN_ELECTRON_BEAM_OFF:
16809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        case TURN_ELECTRON_BEAM_ON:
16818e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross        case BLANK:
16828e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross        case UNBLANK:
1683edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        {
1684edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // codes that require permission check
1685edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            IPCThreadState* ipc = IPCThreadState::self();
1686edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int pid = ipc->getCallingPid();
1687a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian            const int uid = ipc->getCallingUid();
168899b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
168999b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) {
1690e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block                ALOGE("Permission Denial: "
1691375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                        "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
1692375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                return PERMISSION_DENIED;
1693edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
16941b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
16951b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
16961b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        case CAPTURE_SCREEN:
16971b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
16981b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            // codes that require permission check
16991b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
17001b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int pid = ipc->getCallingPid();
17011b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int uid = ipc->getCallingUid();
170299b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
170399b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) {
1704e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block                ALOGE("Permission Denial: "
17051b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                        "can't read framebuffer pid=%d, uid=%d", pid, uid);
17061b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                return PERMISSION_DENIED;
17071b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            }
17081b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
1709edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1710edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
17111b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
1712edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
1713edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
1714b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        CHECK_INTERFACE(ISurfaceComposer, data, reply);
171599ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten        if (CC_UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) {
1716375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
1717375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int pid = ipc->getCallingPid();
1718375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int uid = ipc->getCallingUid();
1719e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block            ALOGE("Permission Denial: "
1720375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                    "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
1721edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return PERMISSION_DENIED;
1722edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1723edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int n;
1724edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        switch (code) {
172501b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian            case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE
172635b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian            case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE
1727edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1728edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1002:  // SHOW_UPDATES
1729edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                n = data.readInt32();
1730edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDebugRegion = n ? n : (mDebugRegion ? 0 : 1);
173153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
173253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
1733edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1734edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1004:{ // repaint everything
173553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
1736cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
1737cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            }
1738cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            case 1005:{ // force transaction
1739cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
1740cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
1741edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
17424d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            case 1006:{ // send empty update
17434d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian                signalRefresh();
17444d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian                return NO_ERROR;
17454d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            }
174653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian            case 1008:  // toggle use of hw composer
174753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                n = data.readInt32();
174853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                mDebugDisableHWC = n ? 1 : 0;
174953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
175053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
175153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                return NO_ERROR;
1752a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian            case 1009:  // toggle use of transform hint
1753a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                n = data.readInt32();
1754a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                mDebugDisableTransformHint = n ? 1 : 0;
1755a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                invalidateHwcGeometry();
1756a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                repaintEverything();
1757a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                return NO_ERROR;
1758edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1010:  // interrogate.
175901b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian                reply->writeInt32(0);
1760edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(0);
1761edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(mDebugRegion);
1762b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                reply->writeInt32(0);
176312839bee29bdcc65731b4d42029cc59e2320c5c4Dianne Hackborn                reply->writeInt32(mDebugDisableHWC);
1764edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1765edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1013: {
1766edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                Mutex::Autolock _l(mStateLock);
1767edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                const DisplayHardware& hw(graphicPlane(0).displayHardware());
1768edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(hw.getPageFlipCount());
1769edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1770edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return NO_ERROR;
1771edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1772edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1773edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return err;
1774edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1775edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
177653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopianvoid SurfaceFlinger::repaintEverything() {
177753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
17780dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    const Rect bounds(hw.getBounds());
17790dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    setInvalidateRegion(Region(bounds));
178099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    signalTransaction();
178153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian}
178253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian
17830dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopianvoid SurfaceFlinger::setInvalidateRegion(const Region& reg) {
17840dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    Mutex::Autolock _l(mInvalidateLock);
17850dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    mInvalidateRegion = reg;
17860dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian}
17870dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian
17880dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias AgopianRegion SurfaceFlinger::getAndClearInvalidateRegion() {
17890dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    Mutex::Autolock _l(mInvalidateLock);
17900dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    Region reg(mInvalidateRegion);
17910dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    mInvalidateRegion.clear();
17920dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    return reg;
17930dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian}
17940dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian
179559119e658a12279e8fff508f8773843de2d90917Mathias Agopian// ---------------------------------------------------------------------------
179659119e658a12279e8fff508f8773843de2d90917Mathias Agopian
1797118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopianstatus_t SurfaceFlinger::renderScreenToTexture(DisplayID dpy,
1798118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        GLuint* textureName, GLfloat* uOut, GLfloat* vOut)
1799118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{
1800118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    Mutex::Autolock _l(mStateLock);
1801118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    return renderScreenToTextureLocked(dpy, textureName, uOut, vOut);
1802118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
1803118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
18049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::renderScreenToTextureLocked(DisplayID dpy,
18059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        GLuint* textureName, GLfloat* uOut, GLfloat* vOut)
180659119e658a12279e8fff508f8773843de2d90917Mathias Agopian{
180722ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian    ATRACE_CALL();
180822ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian
180959119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
181059119e658a12279e8fff508f8773843de2d90917Mathias Agopian        return INVALID_OPERATION;
181159119e658a12279e8fff508f8773843de2d90917Mathias Agopian
181259119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // get screen geometry
181359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    const DisplayHardware& hw(graphicPlane(dpy).displayHardware());
181459119e658a12279e8fff508f8773843de2d90917Mathias Agopian    const uint32_t hw_w = hw.getWidth();
181559119e658a12279e8fff508f8773843de2d90917Mathias Agopian    const uint32_t hw_h = hw.getHeight();
181659119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLfloat u = 1;
181759119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLfloat v = 1;
181859119e658a12279e8fff508f8773843de2d90917Mathias Agopian
181959119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // make sure to clear all GL error flags
182059119e658a12279e8fff508f8773843de2d90917Mathias Agopian    while ( glGetError() != GL_NO_ERROR ) ;
182159119e658a12279e8fff508f8773843de2d90917Mathias Agopian
182259119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // create a FBO
182359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLuint name, tname;
182459119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glGenTextures(1, &tname);
182559119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
1826a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1827a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
18289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
18299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            hw_w, hw_h, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
183059119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (glGetError() != GL_NO_ERROR) {
1831015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian        while ( glGetError() != GL_NO_ERROR ) ;
183259119e658a12279e8fff508f8773843de2d90917Mathias Agopian        GLint tw = (2 << (31 - clz(hw_w)));
183359119e658a12279e8fff508f8773843de2d90917Mathias Agopian        GLint th = (2 << (31 - clz(hw_h)));
18349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
18359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian                tw, th, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
183659119e658a12279e8fff508f8773843de2d90917Mathias Agopian        u = GLfloat(hw_w) / tw;
183759119e658a12279e8fff508f8773843de2d90917Mathias Agopian        v = GLfloat(hw_h) / th;
183859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    }
183959119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glGenFramebuffersOES(1, &name);
184059119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
18419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES,
18429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0);
184359119e658a12279e8fff508f8773843de2d90917Mathias Agopian
18449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // redraw the screen entirely...
1845c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_EXTERNAL_OES);
1846c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_2D);
18479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glClearColor(0,0,0,1);
18489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glClear(GL_COLOR_BUFFER_BIT);
1849a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glMatrixMode(GL_MODELVIEW);
1850a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glLoadIdentity();
18519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
18529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const size_t count = layers.size();
18539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (size_t i=0 ; i<count ; ++i) {
18549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
18559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        layer->drawForSreenShot();
18569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
185759119e658a12279e8fff508f8773843de2d90917Mathias Agopian
1858118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    hw.compositionComplete();
1859118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
18609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // back to main framebuffer
18619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
18629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDeleteFramebuffersOES(1, &name);
186359119e658a12279e8fff508f8773843de2d90917Mathias Agopian
18649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *textureName = tname;
18659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *uOut = u;
18669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *vOut = v;
18679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
18689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
186959119e658a12279e8fff508f8773843de2d90917Mathias Agopian
18709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// ---------------------------------------------------------------------------
187159119e658a12279e8fff508f8773843de2d90917Mathias Agopian
1872ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopianclass VSyncWaiter {
1873ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    DisplayEventReceiver::Event buffer[4];
1874ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    sp<Looper> looper;
1875ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    sp<IDisplayEventConnection> events;
1876ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    sp<BitTube> eventTube;
1877ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopianpublic:
1878ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    VSyncWaiter(const sp<EventThread>& eventThread) {
1879ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        looper = new Looper(true);
1880ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        events = eventThread->createEventConnection();
1881ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        eventTube = events->getDataChannel();
1882ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        looper->addFd(eventTube->getFd(), 0, ALOOPER_EVENT_INPUT, 0, 0);
1883ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        events->requestNextVsync();
1884ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    }
1885ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
1886ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    void wait() {
1887ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        ssize_t n;
1888ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
1889ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        looper->pollOnce(-1);
1890ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        // we don't handle any errors here, it doesn't matter
1891ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        // and we don't want to take the risk to get stuck.
1892ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
1893ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        // drain the events...
1894ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        while ((n = DisplayEventReceiver::getEvents(
1895ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian                eventTube, buffer, 4)) > 0) ;
1896ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
1897ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        events->requestNextVsync();
1898ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    }
1899ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian};
1900ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
19019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::electronBeamOffAnimationImplLocked()
19029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
19039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // get screen geometry
19049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
19059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_w = hw.getWidth();
19069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_h = hw.getHeight();
1907a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    const Region screenBounds(hw.getBounds());
190859119e658a12279e8fff508f8773843de2d90917Mathias Agopian
19099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat u, v;
19109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLuint tname;
1911118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    status_t result = renderScreenToTextureLocked(0, &tname, &u, &v);
19129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (result != NO_ERROR) {
19139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return result;
19149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
191559119e658a12279e8fff508f8773843de2d90917Mathias Agopian
19169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat vtx[8];
1917a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    const GLfloat texCoords[4][2] = { {0,0}, {0,v}, {u,v}, {u,0} };
19189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
19199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
19209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
19219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1922b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1923b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
19249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
19259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
19269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glVertexPointer(2, GL_FLOAT, 0, vtx);
19279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
1928ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    /*
1929ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     * Texture coordinate mapping
1930ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *
1931ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *                 u
1932ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *    1 +----------+---+
1933ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |     |    |   |  image is inverted
1934ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |     V    |   |  w.r.t. the texture
1935ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *  1-v +----------+   |  coordinates
1936ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |              |
1937ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |              |
1938ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |              |
1939ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *    0 +--------------+
1940ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      0              1
1941ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *
1942ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     */
1943ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian
19449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class s_curve_interpolator {
19459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float nbFrames, s, v;
19469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
19479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        s_curve_interpolator(int nbFrames, float s)
19489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : nbFrames(1.0f / (nbFrames-1)), s(s),
19499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian          v(1.0f + expf(-s + 0.5f*s)) {
19509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
19519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float operator()(int f) {
19529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const float x = f * nbFrames;
19539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f;
19549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
19559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
19569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class v_stretch {
19589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
19599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
19609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        v_stretch(uint32_t hw_w, uint32_t hw_h)
19619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
19629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
19639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
19649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w + (hw_w * v);
19659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = hw_h - (hw_h * v);
19669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
19679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
1968ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[0] = x;         vtx[1] = y;
1969ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
1970ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
1971ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
19729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
19739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
19749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class h_stretch {
19769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
19779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
19789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        h_stretch(uint32_t hw_w, uint32_t hw_h)
19799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
198059119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
19819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
19829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w - (hw_w * v);
19839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = 1.0f;
19849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
19859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
1986ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[0] = x;         vtx[1] = y;
1987ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
1988ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
1989ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
19909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
19919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
19929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
1993ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    VSyncWaiter vsync(mEventThread);
1994ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
19959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // the full animation is 24 frames
1996ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    char value[PROPERTY_VALUE_MAX];
1997ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    property_get("debug.sf.electron_frames", value, "24");
1998ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    int nbFrames = (atoi(value) + 1) >> 1;
1999ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    if (nbFrames <= 0) // just in case
2000ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian        nbFrames = 24;
2001ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian
20029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itr(nbFrames, 7.5f);
20039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itg(nbFrames, 8.0f);
20049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itb(nbFrames, 8.5f);
20059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    v_stretch vverts(hw_w, hw_h);
2007a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian
2008a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glMatrixMode(GL_TEXTURE);
2009a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glLoadIdentity();
2010a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glMatrixMode(GL_MODELVIEW);
2011a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glLoadIdentity();
2012a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian
20139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnable(GL_BLEND);
20149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBlendFunc(GL_ONE, GL_ONE);
20159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=0 ; i<nbFrames ; i++) {
20169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float x, y, w, h;
20179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vr = itr(i);
20189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vg = itg(i);
20199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vb = itb(i);
20209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2021ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        // wait for vsync
2022ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        vsync.wait();
2023ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
20249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // clear screen
20259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(1,1,1,1);
20269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
20279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glEnable(GL_TEXTURE_2D);
202859119e658a12279e8fff508f8773843de2d90917Mathias Agopian
20299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the red plane
20309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vr);
20319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(1,0,0,1);
20329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
20339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the green plane
20359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vg);
20369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,1,0,1);
20379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
20389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the blue plane
20409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vb);
20419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,0,1,1);
20429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
20439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the white highlight (we use the last vertices)
204559119e658a12279e8fff508f8773843de2d90917Mathias Agopian        glDisable(GL_TEXTURE_2D);
204659119e658a12279e8fff508f8773843de2d90917Mathias Agopian        glColorMask(1,1,1,1);
20479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColor4f(vg, vg, vg, 1);
20489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
20499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
20509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
20519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    h_stretch hverts(hw_w, hw_h);
20539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_BLEND);
20549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_TEXTURE_2D);
20559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
20569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=0 ; i<nbFrames ; i++) {
20579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float v = itg(i);
20589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hverts(vtx, v);
2059ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
2060ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        // wait for vsync
2061ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        vsync.wait();
2062ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
20639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
20649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColor4f(1-v, 1-v, 1-v, 1);
20659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
20669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
20679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
20689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
20709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
20719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDeleteTextures(1, &tname);
2072a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    glDisable(GL_TEXTURE_2D);
2073c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_BLEND);
20749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
20759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
20769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::electronBeamOnAnimationImplLocked()
20789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
20799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    status_t result = PERMISSION_DENIED;
20809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
20829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return INVALID_OPERATION;
20839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // get screen geometry
20869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
20879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_w = hw.getWidth();
20889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_h = hw.getHeight();
20899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const Region screenBounds(hw.bounds());
20909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat u, v;
20929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLuint tname;
20939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    result = renderScreenToTextureLocked(0, &tname, &u, &v);
20949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (result != NO_ERROR) {
20959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return result;
20969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
20979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat vtx[8];
20999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const GLfloat texCoords[4][2] = { {0,v}, {0,0}, {u,0}, {u,v} };
21009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
21019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
21029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
21039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2104b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2105b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
21069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
21079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
21089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glVertexPointer(2, GL_FLOAT, 0, vtx);
21099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class s_curve_interpolator {
21119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float nbFrames, s, v;
21129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
21139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        s_curve_interpolator(int nbFrames, float s)
21149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : nbFrames(1.0f / (nbFrames-1)), s(s),
21159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian          v(1.0f + expf(-s + 0.5f*s)) {
21169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
21179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float operator()(int f) {
21189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const float x = f * nbFrames;
21199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f;
21209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
21219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
21229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class v_stretch {
21249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
21259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
21269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        v_stretch(uint32_t hw_w, uint32_t hw_h)
21279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
212859119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
21299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
21309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w + (hw_w * v);
21319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = hw_h - (hw_h * v);
21329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
21339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
21349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[0] = x;         vtx[1] = y;
21359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
21369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
21379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
21389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
21399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
21409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class h_stretch {
21429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
21439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
21449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        h_stretch(uint32_t hw_w, uint32_t hw_h)
21459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
21469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
21479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
21489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w - (hw_w * v);
21499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = 1.0f;
21509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
21519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
21529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[0] = x;         vtx[1] = y;
21539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
21549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
21559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
21569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
21579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
21589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2159ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    VSyncWaiter vsync(mEventThread);
2160ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
2161a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian    // the full animation is 12 frames
2162a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian    int nbFrames = 8;
21639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itr(nbFrames, 7.5f);
21649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itg(nbFrames, 8.0f);
21659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itb(nbFrames, 8.5f);
21669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    h_stretch hverts(hw_w, hw_h);
21689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_BLEND);
21699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_TEXTURE_2D);
21709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
21719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=nbFrames-1 ; i>=0 ; i--) {
21729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float v = itg(i);
21739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hverts(vtx, v);
2174ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
2175ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        // wait for vsync
2176ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        vsync.wait();
2177ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
21789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
21799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColor4f(1-v, 1-v, 1-v, 1);
21809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
21819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
21829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
21839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2184a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian    nbFrames = 4;
21859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    v_stretch vverts(hw_w, hw_h);
21869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnable(GL_BLEND);
21879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBlendFunc(GL_ONE, GL_ONE);
21889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=nbFrames-1 ; i>=0 ; i--) {
21899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float x, y, w, h;
21909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vr = itr(i);
21919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vg = itg(i);
21929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vb = itb(i);
219359119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2194ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        // wait for vsync
2195ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        vsync.wait();
2196ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
21979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // clear screen
219859119e658a12279e8fff508f8773843de2d90917Mathias Agopian        glColorMask(1,1,1,1);
21999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
22009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glEnable(GL_TEXTURE_2D);
22019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the red plane
22039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vr);
22049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(1,0,0,1);
22059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
22069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the green plane
22089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vg);
22099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,1,0,1);
22109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
22119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the blue plane
22139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vb);
22149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,0,1,1);
22159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
22169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
221859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    }
221959119e658a12279e8fff508f8773843de2d90917Mathias Agopian
22209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
22219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
222259119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glDeleteTextures(1, &tname);
2223a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    glDisable(GL_TEXTURE_2D);
2224c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_BLEND);
222559119e658a12279e8fff508f8773843de2d90917Mathias Agopian
22269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
22279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
22289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// ---------------------------------------------------------------------------
22309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2231abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOffImplLocked(int32_t mode)
22329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
223322ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian    ATRACE_CALL();
223422ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian
22359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    DisplayHardware& hw(graphicPlane(0).editDisplayHardware());
22369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (!hw.canDraw()) {
22379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // we're already off
22389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return NO_ERROR;
22399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
22407ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian
22417ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian    // turn off hwc while we're doing the animation
22427ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian    hw.getHwComposer().disable();
22437ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian    // and make sure to turn it back on (if needed) next time we compose
22447ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian    invalidateHwcGeometry();
22457ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian
2246abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    if (mode & ISurfaceComposer::eElectronBeamAnimationOff) {
2247abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        electronBeamOffAnimationImplLocked();
2248abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    }
2249abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian
2250abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    // always clear the whole screen at the end of the animation
2251abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    glClearColor(0,0,0,1);
2252abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    glClear(GL_COLOR_BUFFER_BIT);
2253abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    hw.flip( Region(hw.bounds()) );
2254abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian
2255015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian    return NO_ERROR;
225659119e658a12279e8fff508f8773843de2d90917Mathias Agopian}
225759119e658a12279e8fff508f8773843de2d90917Mathias Agopian
225859119e658a12279e8fff508f8773843de2d90917Mathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOff(int32_t mode)
225959119e658a12279e8fff508f8773843de2d90917Mathias Agopian{
226059119e658a12279e8fff508f8773843de2d90917Mathias Agopian    class MessageTurnElectronBeamOff : public MessageBase {
226159119e658a12279e8fff508f8773843de2d90917Mathias Agopian        SurfaceFlinger* flinger;
2262abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        int32_t mode;
226359119e658a12279e8fff508f8773843de2d90917Mathias Agopian        status_t result;
226459119e658a12279e8fff508f8773843de2d90917Mathias Agopian    public:
2265abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        MessageTurnElectronBeamOff(SurfaceFlinger* flinger, int32_t mode)
2266abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            : flinger(flinger), mode(mode), result(PERMISSION_DENIED) {
226759119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
226859119e658a12279e8fff508f8773843de2d90917Mathias Agopian        status_t getResult() const {
226959119e658a12279e8fff508f8773843de2d90917Mathias Agopian            return result;
227059119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
227159119e658a12279e8fff508f8773843de2d90917Mathias Agopian        virtual bool handler() {
227259119e658a12279e8fff508f8773843de2d90917Mathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
2273abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            result = flinger->turnElectronBeamOffImplLocked(mode);
227459119e658a12279e8fff508f8773843de2d90917Mathias Agopian            return true;
227559119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
227659119e658a12279e8fff508f8773843de2d90917Mathias Agopian    };
227759119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2278abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    sp<MessageBase> msg = new MessageTurnElectronBeamOff(this, mode);
227959119e658a12279e8fff508f8773843de2d90917Mathias Agopian    status_t res = postMessageSync(msg);
228059119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (res == NO_ERROR) {
228159119e658a12279e8fff508f8773843de2d90917Mathias Agopian        res = static_cast<MessageTurnElectronBeamOff*>( msg.get() )->getResult();
22829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // work-around: when the power-manager calls us we activate the
22849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // animation. eventually, the "on" animation will be called
22859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // by the power-manager itself
2286abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        mElectronBeamAnimationMode = mode;
228759119e658a12279e8fff508f8773843de2d90917Mathias Agopian    }
228859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    return res;
228959119e658a12279e8fff508f8773843de2d90917Mathias Agopian}
229059119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2291edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
2292edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2293abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOnImplLocked(int32_t mode)
22949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
22959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    DisplayHardware& hw(graphicPlane(0).editDisplayHardware());
22969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (hw.canDraw()) {
22979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // we're already on
22989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return NO_ERROR;
22999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
2300abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    if (mode & ISurfaceComposer::eElectronBeamAnimationOn) {
2301abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        electronBeamOnAnimationImplLocked();
2302abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    }
2303a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian
2304a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian    // make sure to redraw the whole screen when the animation is done
2305a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian    mDirtyRegion.set(hw.bounds());
230699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    signalTransaction();
2307a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian
2308015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian    return NO_ERROR;
23099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
23109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
23119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOn(int32_t mode)
23129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
23139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class MessageTurnElectronBeamOn : public MessageBase {
23149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        SurfaceFlinger* flinger;
2315abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        int32_t mode;
23169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        status_t result;
23179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
2318abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        MessageTurnElectronBeamOn(SurfaceFlinger* flinger, int32_t mode)
2319abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            : flinger(flinger), mode(mode), result(PERMISSION_DENIED) {
23209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
23219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        status_t getResult() const {
23229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return result;
23239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
23249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        virtual bool handler() {
23259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
2326abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            result = flinger->turnElectronBeamOnImplLocked(mode);
23279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return true;
23289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
23299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
23309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2331abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    postMessageAsync( new MessageTurnElectronBeamOn(this, mode) );
23329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
23339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
23349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
23359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// ---------------------------------------------------------------------------
23369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
233774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopianstatus_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy,
233874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        sp<IMemoryHeap>* heap,
233974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t* w, uint32_t* h, PixelFormat* f,
2340bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t sw, uint32_t sh,
2341bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ, uint32_t maxLayerZ)
234274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{
2343fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian    ATRACE_CALL();
2344fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian
234574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    status_t result = PERMISSION_DENIED;
234674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
234774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // only one display supported for now
234899ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten    if (CC_UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
234974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return BAD_VALUE;
235074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
235174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
235274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return INVALID_OPERATION;
235374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
235474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // get screen geometry
235574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const DisplayHardware& hw(graphicPlane(dpy).displayHardware());
235674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const uint32_t hw_w = hw.getWidth();
235774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const uint32_t hw_h = hw.getHeight();
235874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
235974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    if ((sw > hw_w) || (sh > hw_h))
236074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return BAD_VALUE;
236174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
236274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    sw = (!sw) ? hw_w : sw;
236374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    sh = (!sh) ? hw_h : sh;
236474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const size_t size = sw * sh * 4;
236574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
23669d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block    //ALOGD("screenshot: sw=%d, sh=%d, minZ=%d, maxZ=%d",
23671c71a47a6db679a3212f0c99e14f330d6da500faMathias Agopian    //        sw, sh, minLayerZ, maxLayerZ);
2368c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
236974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // make sure to clear all GL error flags
237074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    while ( glGetError() != GL_NO_ERROR ) ;
237174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
237274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // create a FBO
237374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    GLuint name, tname;
237474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glGenRenderbuffersOES(1, &tname);
237574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindRenderbufferOES(GL_RENDERBUFFER_OES, tname);
237674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA8_OES, sw, sh);
2377fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian
237874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glGenFramebuffersOES(1, &name);
237974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
238074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES,
238174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, tname);
238274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
238374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
2384c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
238574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    if (status == GL_FRAMEBUFFER_COMPLETE_OES) {
238674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
238774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // invert everything, b/c glReadPixel() below will invert the FB
238874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glViewport(0, 0, sw, sh);
238974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_PROJECTION);
239074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glPushMatrix();
239174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glLoadIdentity();
2392ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian        glOrthof(0, hw_w, hw_h, 0, 0, 1);
239374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_MODELVIEW);
239474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
239574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // redraw the screen entirely...
239674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glClearColor(0,0,0,1);
239774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
2398f653b897a449e10d6cbfb6e0812f7b0bb02d6482Mathias Agopian
23999575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        const LayerVector& layers(mDrawingState.layersSortedByZ);
24009575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        const size_t count = layers.size();
240174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        for (size_t i=0 ; i<count ; ++i) {
240274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            const sp<LayerBase>& layer(layers[i]);
2403b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian            const uint32_t flags = layer->drawingState().flags;
2404b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian            if (!(flags & ISurfaceComposer::eLayerHidden)) {
2405b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                const uint32_t z = layer->drawingState().z;
2406b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                if (z >= minLayerZ && z <= maxLayerZ) {
2407b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                    layer->drawForSreenShot();
2408b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                }
2409bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian            }
241074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        }
241174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
241274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // check for errors and return screen capture
241374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        if (glGetError() != GL_NO_ERROR) {
241474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // error while rendering
241574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            result = INVALID_OPERATION;
241674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        } else {
241774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // allocate shared memory large enough to hold the
241874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // screen capture
241974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            sp<MemoryHeapBase> base(
242074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    new MemoryHeapBase(size, 0, "screen-capture") );
242174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            void* const ptr = base->getBase();
242274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            if (ptr) {
242374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                // capture the screen with glReadPixels()
2424fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian                ScopedTrace _t(ATRACE_TAG, "glReadPixels");
242574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                glReadPixels(0, 0, sw, sh, GL_RGBA, GL_UNSIGNED_BYTE, ptr);
242674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                if (glGetError() == GL_NO_ERROR) {
242774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *heap = base;
242874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *w = sw;
242974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *h = sh;
243074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *f = PIXEL_FORMAT_RGBA_8888;
243174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    result = NO_ERROR;
243274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                }
243374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            } else {
243474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                result = NO_MEMORY;
243574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            }
243674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        }
243774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glViewport(0, 0, hw_w, hw_h);
243874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_PROJECTION);
243974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glPopMatrix();
244074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_MODELVIEW);
244174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    } else {
244274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        result = BAD_VALUE;
244374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    }
244474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
244574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // release FBO resources
244674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
244774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glDeleteRenderbuffersOES(1, &tname);
244874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glDeleteFramebuffersOES(1, &name);
2449e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian
2450e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian    hw.compositionComplete();
2451e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian
24529d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block    // ALOGD("screenshot: result = %s", result<0 ? strerror(result) : "OK");
2453c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
245474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    return result;
245574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian}
245674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
245774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
24581b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopianstatus_t SurfaceFlinger::captureScreen(DisplayID dpy,
24591b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        sp<IMemoryHeap>* heap,
246074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t* width, uint32_t* height, PixelFormat* format,
2461bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t sw, uint32_t sh,
2462bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ, uint32_t maxLayerZ)
24631b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian{
24641b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    // only one display supported for now
246599ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten    if (CC_UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
24661b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        return BAD_VALUE;
24671b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
24681b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
24691b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        return INVALID_OPERATION;
24701b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
24711b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    class MessageCaptureScreen : public MessageBase {
24721b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        SurfaceFlinger* flinger;
24731b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        DisplayID dpy;
24741b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        sp<IMemoryHeap>* heap;
24751b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        uint32_t* w;
24761b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        uint32_t* h;
24771b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        PixelFormat* f;
247874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t sw;
247974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t sh;
2480bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ;
2481bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t maxLayerZ;
24821b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        status_t result;
24831b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    public:
24841b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        MessageCaptureScreen(SurfaceFlinger* flinger, DisplayID dpy,
248574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                sp<IMemoryHeap>* heap, uint32_t* w, uint32_t* h, PixelFormat* f,
2486bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                uint32_t sw, uint32_t sh,
2487bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                uint32_t minLayerZ, uint32_t maxLayerZ)
24881b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            : flinger(flinger), dpy(dpy),
2489bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              heap(heap), w(w), h(h), f(f), sw(sw), sh(sh),
2490bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              minLayerZ(minLayerZ), maxLayerZ(maxLayerZ),
2491bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              result(PERMISSION_DENIED)
24921b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
24931b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
24941b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        status_t getResult() const {
24951b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            return result;
24961b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
24971b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        virtual bool handler() {
24981b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
24991b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
25001b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            // if we have secure windows, never allow the screen capture
25011b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            if (flinger->mSecureFrameBuffer)
25021b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                return true;
25031b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
250474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            result = flinger->captureScreenImplLocked(dpy,
2505bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                    heap, w, h, f, sw, sh, minLayerZ, maxLayerZ);
25061b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
25071b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            return true;
25081b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
25091b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    };
25101b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
25111b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    sp<MessageBase> msg = new MessageCaptureScreen(this,
2512bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian            dpy, heap, width, height, format, sw, sh, minLayerZ, maxLayerZ);
25131b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    status_t res = postMessageSync(msg);
25141b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    if (res == NO_ERROR) {
25151b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        res = static_cast<MessageCaptureScreen*>( msg.get() )->getResult();
25161b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    }
25171b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    return res;
25181b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian}
25191b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
25201b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// ---------------------------------------------------------------------------
25211b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
2522b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<Layer> SurfaceFlinger::getLayer(const sp<ISurface>& sur) const
2523edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2524b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<Layer> result;
2525b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    Mutex::Autolock _l(mStateLock);
2526b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    result = mLayerMap.valueFor( sur->asBinder() ).promote();
2527b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return result;
2528b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
25297303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
2530b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// ---------------------------------------------------------------------------
253196f0819f81293076e652792794a961543e6750d7Mathias Agopian
25329a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::GraphicBufferAlloc() {}
25339a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
25349a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::~GraphicBufferAlloc() {}
25359a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
25369a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h,
2537d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        PixelFormat format, uint32_t usage, status_t* error) {
25389a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(w, h, format, usage));
25399a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    status_t err = graphicBuffer->initCheck();
2540d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian    *error = err;
2541a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (err != 0 || graphicBuffer->handle == 0) {
2542d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        if (err == NO_MEMORY) {
2543d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian            GraphicBuffer::dumpAllocationsToSystemLog();
2544d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        }
2545e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE("GraphicBufferAlloc::createGraphicBuffer(w=%d, h=%d) "
2546a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian             "failed (%s), handle=%p",
2547a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                w, h, strerror(-err), graphicBuffer->handle);
25489a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis        return 0;
25499a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    }
25509a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    return graphicBuffer;
25519a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis}
25529a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
25539a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis// ---------------------------------------------------------------------------
25549a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
2555edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane::GraphicPlane()
2556edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    : mHw(0)
2557edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2558edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2559edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2560edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane::~GraphicPlane() {
2561edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    delete mHw;
2562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2563edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2564edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool GraphicPlane::initialized() const {
2565edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return mHw ? true : false;
2566edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2567edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
25682b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianint GraphicPlane::getWidth() const {
25692b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    return mWidth;
2570edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2571edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
25722b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianint GraphicPlane::getHeight() const {
25732b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    return mHeight;
25742b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian}
25752b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
25762b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianvoid GraphicPlane::setDisplayHardware(DisplayHardware *hw)
25772b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian{
25782b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mHw = hw;
25792b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
25802b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    // initialize the display orientation transform.
25812b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    // it's a constant that should come from the display driver.
25822b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    int displayOrientation = ISurfaceComposer::eOrientationDefault;
25832b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    char property[PROPERTY_VALUE_MAX];
25842b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    if (property_get("ro.sf.hwrotation", property, NULL) > 0) {
25852b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        //displayOrientation
25862b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        switch (atoi(property)) {
25872b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        case 90:
25882b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            displayOrientation = ISurfaceComposer::eOrientation90;
25892b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            break;
25902b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        case 270:
25912b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            displayOrientation = ISurfaceComposer::eOrientation270;
25922b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            break;
25932b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        }
25942b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    }
25952b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
25962b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float w = hw->getWidth();
25972b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float h = hw->getHeight();
25982b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    GraphicPlane::orientationToTransfrom(displayOrientation, w, h,
25992b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            &mDisplayTransform);
26002b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    if (displayOrientation & ISurfaceComposer::eOrientationSwapMask) {
26012b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayWidth = h;
26022b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayHeight = w;
26032b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    } else {
26042b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayWidth = w;
26052b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayHeight = h;
26062b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    }
26072b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
26082b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    setOrientation(ISurfaceComposer::eOrientationDefault);
2609edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2610edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2611edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t GraphicPlane::orientationToTransfrom(
2612edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int orientation, int w, int h, Transform* tr)
2613eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian{
2614eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    uint32_t flags = 0;
2615edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (orientation) {
2616edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientationDefault:
2617eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_0;
2618eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        break;
2619edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientation90:
2620eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_90;
2621edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
2622edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientation180:
2623eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_180;
2624edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
2625edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientation270:
2626eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_270;
2627edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
2628edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    default:
2629edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return BAD_VALUE;
2630edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2631eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    tr->set(flags, w, h);
2632edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
2633edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2634edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2635edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t GraphicPlane::setOrientation(int orientation)
2636edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2637edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // If the rotation can be handled in hardware, this is where
2638edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // the magic should happen.
26392b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
26402b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const DisplayHardware& hw(displayHardware());
26412b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float w = mDisplayWidth;
26422b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float h = mDisplayHeight;
26432b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mWidth = int(w);
26442b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mHeight = int(h);
26452b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
26462b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    Transform orientationTransform;
2647eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    GraphicPlane::orientationToTransfrom(orientation, w, h,
2648eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian            &orientationTransform);
2649eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    if (orientation & ISurfaceComposer::eOrientationSwapMask) {
2650eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        mWidth = int(h);
2651eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        mHeight = int(w);
2652edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2653eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian
26540d1318b974feba2e6ff13e36a1781343c2fce045Mathias Agopian    mOrientation = orientation;
26552b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mGlobalTransform = mDisplayTransform * orientationTransform;
2656edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
2657edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2658edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2659edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst DisplayHardware& GraphicPlane::displayHardware() const {
2660edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return *mHw;
2661edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2662edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
266359119e658a12279e8fff508f8773843de2d90917Mathias AgopianDisplayHardware& GraphicPlane::editDisplayHardware() {
266459119e658a12279e8fff508f8773843de2d90917Mathias Agopian    return *mHw;
266559119e658a12279e8fff508f8773843de2d90917Mathias Agopian}
266659119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2667edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst Transform& GraphicPlane::transform() const {
2668edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return mGlobalTransform;
2669edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2670edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2671076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias AgopianEGLDisplay GraphicPlane::getEGLDisplay() const {
2672076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return mHw->getEGLDisplay();
2673076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
2674076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
2675edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
2676edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2677edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
2678