SurfaceFlinger.cpp revision 3094df359d1e6e2ae8ca4e935cc093f563804c96
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>
673094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian#include <gui/SurfaceTextureClient.h>
68a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
69bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian#define EGL_VERSION_HW_ANDROID  0x3143
70bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DISPLAY_COUNT       1
72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
73edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
74edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
75edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
7699b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sHardwareTest("android.permission.HARDWARE_TEST");
7799b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER");
7899b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER");
7999b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sDump("android.permission.DUMP");
8099b49840d309727678b77403d6cc9f920111623fMathias Agopian
8199b49840d309727678b77403d6cc9f920111623fMathias Agopian// ---------------------------------------------------------------------------
8299b49840d309727678b77403d6cc9f920111623fMathias Agopian
83edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::SurfaceFlinger()
84edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    :   BnSurfaceComposer(), Thread(false),
85edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mTransactionFlags(0),
8628378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        mTransationPending(false),
87076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved(false),
88edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mBootTime(systemTime()),
89edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mVisibleRegionsDirty(false),
90a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        mHwWorkListDirty(false),
91abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        mElectronBeamAnimationMode(0),
92edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDebugRegion(0),
938afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian        mDebugDDMS(0),
9473d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian        mDebugDisableHWC(0),
95a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian        mDebugDisableTransformHint(0),
969795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInSwapBuffers(0),
979795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastSwapBufferTime(0),
989795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInTransaction(0),
999795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastTransactionTime(0),
1003330b203039dea366d4981db1408a460134b2d2cMathias Agopian        mBootFinished(false),
1013094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        mSecureFrameBuffer(0),
1023094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        mExternalDisplaySurface(EGL_NO_SURFACE)
103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    init();
105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::init()
108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
109a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI("SurfaceFlinger is starting");
110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // debugging stuff...
112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char value[PROPERTY_VALUE_MAX];
1138afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    property_get("debug.sf.showupdates", value, "0");
115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDebugRegion = atoi(value);
1168afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
1173854ed549012f2abf8fea7b0e6db30b104ea5547Colin Cross#ifdef DDMS_DEBUGGING
1188afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    property_get("debug.sf.ddms", value, "0");
1198afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    mDebugDDMS = atoi(value);
1208afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    if (mDebugDDMS) {
1218afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian        DdmConnection::start(getServiceName());
1228afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    }
1235df996211d4e263feb862121cfafa7f9c8eeda68Mathias Agopian#else
1245df996211d4e263feb862121cfafa7f9c8eeda68Mathias Agopian#warning "DDMS_DEBUGGING disabled"
1253854ed549012f2abf8fea7b0e6db30b104ea5547Colin Cross#endif
1268afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
127a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI_IF(mDebugRegion,       "showupdates enabled");
128a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI_IF(mDebugDDMS,         "DDMS debugging enabled");
129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
13199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::onFirstRef()
13299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
13399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.init(this);
13499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
13599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY);
13699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
13799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // Wait for the main thread to be done with its initialization
13899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mReadyToRunBarrier.wait();
13999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
14099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
14199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
142edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::~SurfaceFlinger()
143edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDeleteTextures(1, &mWormholeTexName);
145edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
146edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
14799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::binderDied(const wp<IBinder>& who)
14899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
14999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // the window manager died on us. prepare its eulogy.
15099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
15199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // reset screen orientation
15299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    Vector<ComposerState> state;
15399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    setTransactionState(state, eOrientationDefault, 0);
15499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
15599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // restart the boot-animation
156a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    startBootAnim();
15799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
15899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
1597303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopiansp<IMemoryHeap> SurfaceFlinger::getCblk() const
160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1617303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    return mServerHeap;
162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1647e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopiansp<ISurfaceComposerClient> SurfaceFlinger::createConnection()
165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
16696f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<ISurfaceComposerClient> bclient;
16796f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<Client> client(new Client(this));
16896f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = client->initCheck();
16996f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR) {
17096f0819f81293076e652792794a961543e6750d7Mathias Agopian        bclient = client;
171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return bclient;
173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1759a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc()
1769a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis{
1779a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc());
1789a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    return gba;
1799a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis}
180b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst GraphicPlane& SurfaceFlinger::graphicPlane(int dpy) const
182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
183e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block    ALOGE_IF(uint32_t(dpy) >= DISPLAY_COUNT, "Invalid DisplayID %d", dpy);
184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(mGraphicPlanes[dpy]);
185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return plane;
186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane& SurfaceFlinger::graphicPlane(int dpy)
189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return const_cast<GraphicPlane&>(
191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const_cast<SurfaceFlinger const *>(this)->graphicPlane(dpy));
192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::bootFinished()
195edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t now = systemTime();
197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t duration = now - mBootTime;
198a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
1993330b203039dea366d4981db1408a460134b2d2cMathias Agopian    mBootFinished = true;
2001f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
2011f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // wait patiently for the window manager death
2021f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    const String16 name("window");
2031f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    sp<IBinder> window(defaultServiceManager()->getService(name));
2041f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    if (window != 0) {
2051f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian        window->linkToDeath(this);
2061f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    }
2071f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
2081f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // stop boot animation
209a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // formerly we would just kill the process, but we now ask it to exit so it
210a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // can choose where to stop the animation.
211a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("service.bootanim.exit", "1");
212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic inline uint16_t pack565(int r, int g, int b) {
215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return (r<<11)|(g<<5)|b;
216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
217edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::readyToRun()
219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
220a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI(   "SurfaceFlinger's main thread ready to run. "
221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            "Initializing graphics H/W...");
222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // we only support one display currently
224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int dpy = 0;
225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    {
227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // initialize the main display
228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GraphicPlane& plane(graphicPlane(dpy));
229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        DisplayHardware* const hw = new DisplayHardware(this, dpy);
230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        plane.setDisplayHardware(hw);
231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2337303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    // create the shared control-block
2347303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    mServerHeap = new MemoryHeapBase(4096,
2357303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian            MemoryHeapBase::READ_ONLY, "SurfaceFlinger read-only heap");
236e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block    ALOGE_IF(mServerHeap==0, "can't create shared memory dealer");
2378b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
2387303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    mServerCblk = static_cast<surface_flinger_cblk_t*>(mServerHeap->getBase());
239e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block    ALOGE_IF(mServerCblk==0, "can't get to shared control block's address");
2408b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
2417303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    new(mServerCblk) surface_flinger_cblk_t;
2427303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize primary screen
244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // (other display should be initialized in the same manner, but
245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // asynchronously, as they could come and go. None of this is supported
246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // yet).
247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(graphicPlane(dpy));
248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw = plane.displayHardware();
249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint32_t w = hw.getWidth();
250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint32_t h = hw.getHeight();
251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint32_t f = hw.getFormat();
252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    hw.makeCurrent();
253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize the shared control block
255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mServerCblk->connected |= 1<<dpy;
256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    display_cblk_t* dcblk = mServerCblk->displays + dpy;
257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    memset(dcblk, 0, sizeof(display_cblk_t));
2582b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    dcblk->w            = plane.getWidth();
2592b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    dcblk->h            = plane.getHeight();
260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->format       = f;
261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->orientation  = ISurfaceComposer::eOrientationDefault;
262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->xdpi         = hw.getDpiX();
263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->ydpi         = hw.getDpiY();
264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->fps          = hw.getRefreshRate();
265edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->density      = hw.getDensity();
266edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
267edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // Initialize OpenGL|ES
268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
2698b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber    glPixelStorei(GL_PACK_ALIGNMENT, 4);
270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glEnableClientState(GL_VERTEX_ARRAY);
271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glShadeModel(GL_FLAT);
272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_DITHER);
273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_CULL_FACE);
274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint16_t g0 = pack565(0x0F,0x1F,0x0F);
276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint16_t g1 = pack565(0x17,0x2f,0x17);
2779575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    const uint16_t wormholeTexData[4] = { g0, g1, g1, g0 };
278edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glGenTextures(1, &mWormholeTexName);
279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glBindTexture(GL_TEXTURE_2D, mWormholeTexName);
280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
284edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0,
2859575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis            GL_RGB, GL_UNSIGNED_SHORT_5_6_5, wormholeTexData);
2869575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis
2879575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    const uint16_t protTexData[] = { pack565(0x03, 0x03, 0x03) };
2889575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glGenTextures(1, &mProtectedTexName);
2899575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glBindTexture(GL_TEXTURE_2D, mProtectedTexName);
2909575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2919575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2929575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
2939575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
2949575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0,
2959575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis            GL_RGB, GL_UNSIGNED_SHORT_5_6_5, protTexData);
296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glViewport(0, 0, w, h);
298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glMatrixMode(GL_PROJECTION);
299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glLoadIdentity();
300ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    // put the origin in the left-bottom corner
301ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    glOrthof(0, w, 0, h, 0, 1); // l=0, r=w ; b=0, t=h
302edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
303d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
304d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian    // start the EventThread
305d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian    mEventThread = new EventThread(this);
3068aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian    mEventQueue.setEventThread(mEventThread);
307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     *  We're now ready to accept clients...
310edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
311edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
312d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian    mReadyToRunBarrier.open();
313d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
314a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    // start boot animation
315a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    startBootAnim();
3168b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
320a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopianvoid SurfaceFlinger::startBootAnim() {
321a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // start boot animation
322a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("service.bootanim.exit", "0");
323a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("ctl.start", "bootanim");
324a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian}
325a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian
326edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
327d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
328582270d69db94286a248bd829f1ae6f910d45124Jamie Gennisbool SurfaceFlinger::authenticateSurfaceTexture(
329582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis        const sp<ISurfaceTexture>& surfaceTexture) const {
330134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    Mutex::Autolock _l(mStateLock);
331582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis    sp<IBinder> surfaceTextureBinder(surfaceTexture->asBinder());
332134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
333134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // Check the visible layer list for the ISurface
334134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
335134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    size_t count = currentLayers.size();
336134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    for (size_t i=0 ; i<count ; i++) {
337134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        const sp<LayerBase>& layer(currentLayers[i]);
338134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        sp<LayerBaseClient> lbc(layer->getLayerBaseClient());
339582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis        if (lbc != NULL) {
340582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder();
341582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            if (lbcBinder == surfaceTextureBinder) {
342582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis                return true;
343582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            }
344134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        }
345134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    }
346134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
347134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // Check the layers in the purgatory.  This check is here so that if a
348582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis    // SurfaceTexture gets destroyed before all the clients are done using it,
349582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis    // the error will not be reported as "surface XYZ is not authenticated", but
350134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // will instead fail later on when the client tries to use the surface,
351134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // which should be reported as "surface XYZ returned an -ENODEV".  The
352134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // purgatorized layers are no less authentic than the visible ones, so this
353134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // should not cause any harm.
354134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    size_t purgatorySize =  mLayerPurgatory.size();
355134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    for (size_t i=0 ; i<purgatorySize ; i++) {
356134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
357134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        sp<LayerBaseClient> lbc(layer->getLayerBaseClient());
358582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis        if (lbc != NULL) {
359582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder();
360582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            if (lbcBinder == surfaceTextureBinder) {
361582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis                return true;
362582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            }
363134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        }
364134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    }
365134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
366134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    return false;
367134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis}
368134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
369d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian// ----------------------------------------------------------------------------
370d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
371d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopiansp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection() {
3728aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian    return mEventThread->createEventConnection();
373bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian}
374bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
3753094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopianvoid SurfaceFlinger::connectDisplay(const sp<ISurfaceTexture> display) {
3763094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
3773094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    EGLSurface result = EGL_NO_SURFACE;
3783094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    EGLSurface old_surface = EGL_NO_SURFACE;
3793094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    sp<SurfaceTextureClient> stc;
3803094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
3813094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    if (display != NULL) {
3823094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        stc = new SurfaceTextureClient(display);
3833094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        result = eglCreateWindowSurface(hw.getEGLDisplay(),
3843094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                hw.getEGLConfig(), (EGLNativeWindowType)stc.get(), NULL);
3853094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        ALOGE_IF(result == EGL_NO_SURFACE,
3863094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                "eglCreateWindowSurface failed (ISurfaceTexture=%p)",
3873094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                display.get());
3883094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    }
3893094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
3903094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    { // scope for the lock
3913094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        Mutex::Autolock _l(mStateLock);
3923094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        old_surface = mExternalDisplaySurface;
3933094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        mExternalDisplayNativeWindow = stc;
3943094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        mExternalDisplaySurface = result;
3953094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        ALOGD("mExternalDisplaySurface = %p", result);
3963094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    }
3973094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
3983094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    if (old_surface != EGL_NO_SURFACE) {
3993094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        // Note: EGL allows to destroy an object while its current
4003094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        // it will fail to become current next time though.
4013094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        eglDestroySurface(hw.getEGLDisplay(), old_surface);
4023094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    }
4033094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian}
4043094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
4053094df359d1e6e2ae8ca4e935cc093f563804c96Mathias AgopianEGLSurface SurfaceFlinger::getExternalDisplaySurface() const {
4063094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    Mutex::Autolock _l(mStateLock);
4073094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    return mExternalDisplaySurface;
4083094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian}
4093094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
410edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
41199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
41299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::waitForEvent() {
41399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.waitMessage();
41499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
41599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
41699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalTransaction() {
41799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.invalidate();
41899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
41999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
42099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalLayerUpdate() {
42199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.invalidate();
42299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
42399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
42499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalRefresh() {
42599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.refresh();
42699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
42799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
42899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg,
42999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        nsecs_t reltime, uint32_t flags) {
43099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return mEventQueue.postMessage(msg, reltime);
43199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
43299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
43399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,
43499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        nsecs_t reltime, uint32_t flags) {
43599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    status_t res = mEventQueue.postMessage(msg, reltime);
43699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    if (res == NO_ERROR) {
43799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        msg->wait();
43899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    }
43999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return res;
44099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
441edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
442edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool SurfaceFlinger::threadLoop()
443edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
444edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    waitForEvent();
44599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return true;
44699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
447edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
44899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::onMessageReceived(int32_t what)
44999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
4501c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
45199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    switch (what) {
45269a655caef30663403802281210363f643ceb946Mathias Agopian        case MessageQueue::REFRESH: {
45369a655caef30663403802281210363f643ceb946Mathias Agopian//        case MessageQueue::INVALIDATE: {
45499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            // if we're in a global transaction, don't do anything.
45599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
45699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            uint32_t transactionFlags = peekTransactionFlags(mask);
45799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            if (CC_UNLIKELY(transactionFlags)) {
45899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian                handleTransaction(transactionFlags);
45999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            }
460edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
46199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            // post surfaces (if needed)
46299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            handlePageFlip();
463edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
46469a655caef30663403802281210363f643ceb946Mathias Agopian//            signalRefresh();
46569a655caef30663403802281210363f643ceb946Mathias Agopian//
46669a655caef30663403802281210363f643ceb946Mathias Agopian//        } break;
46769a655caef30663403802281210363f643ceb946Mathias Agopian//
46869a655caef30663403802281210363f643ceb946Mathias Agopian//        case MessageQueue::REFRESH: {
4693a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian
470c9ca7011501cb8730ce4e6e527cb402adb7a0178Mathias Agopian            handleRefresh();
471a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
472303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian            const DisplayHardware& hw(graphicPlane(0).displayHardware());
473303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian
47469a655caef30663403802281210363f643ceb946Mathias Agopian//            if (mDirtyRegion.isEmpty()) {
47569a655caef30663403802281210363f643ceb946Mathias Agopian//                return;
47669a655caef30663403802281210363f643ceb946Mathias Agopian//            }
47769a655caef30663403802281210363f643ceb946Mathias Agopian
478b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian            if (CC_UNLIKELY(mHwWorkListDirty)) {
479b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian                // build the h/w work list
480b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian                handleWorkList();
481b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian            }
482303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian
483b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian            if (CC_LIKELY(hw.canDraw())) {
484b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian                // repaint the framebuffer (if needed)
485b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian                handleRepaint();
486b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian                // inform the h/w that we're done compositing
487b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian                hw.compositionComplete();
488b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian                postFramebuffer();
489c9ca7011501cb8730ce4e6e527cb402adb7a0178Mathias Agopian            } else {
490b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian                // pretend we did the post
491c9ca7011501cb8730ce4e6e527cb402adb7a0178Mathias Agopian                hw.compositionComplete();
49299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            }
493b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian
4943094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian            // render to the external display if we have one
4953094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian            EGLSurface externalDisplaySurface = getExternalDisplaySurface();
4963094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian            if (externalDisplaySurface != EGL_NO_SURFACE) {
4973094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                EGLSurface cur = eglGetCurrentSurface(EGL_DRAW);
4983094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                EGLBoolean success = eglMakeCurrent(eglGetCurrentDisplay(),
4993094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                        externalDisplaySurface, externalDisplaySurface,
5003094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                        eglGetCurrentContext());
5013094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
5023094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                ALOGE_IF(!success, "eglMakeCurrent -> external failed");
5033094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
5043094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                if (success) {
5053094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                    // redraw the screen entirely...
5063094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                    glDisable(GL_TEXTURE_EXTERNAL_OES);
5073094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                    glDisable(GL_TEXTURE_2D);
5083094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                    glClearColor(0,0,0,1);
5093094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                    glClear(GL_COLOR_BUFFER_BIT);
5103094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                    glMatrixMode(GL_MODELVIEW);
5113094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                    glLoadIdentity();
5123094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                    const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
5133094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                    const size_t count = layers.size();
5143094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                    for (size_t i=0 ; i<count ; ++i) {
5153094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                        const sp<LayerBase>& layer(layers[i]);
5163094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                        layer->drawForSreenShot();
5173094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                    }
5183094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
5193094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                    success = eglSwapBuffers(eglGetCurrentDisplay(), externalDisplaySurface);
5203094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                    ALOGE_IF(!success, "external display eglSwapBuffers failed");
5213094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
5223094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                    hw.compositionComplete();
5233094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                }
5243094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
5253094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                success = eglMakeCurrent(eglGetCurrentDisplay(),
5263094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                        cur, cur, eglGetCurrentContext());
5273094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
5283094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                ALOGE_IF(!success, "eglMakeCurrent -> internal failed");
5293094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian            }
5303094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
53199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        } break;
532edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
533edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
534edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
535edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer()
536edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
537841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
538b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian    // mSwapRegion can be empty here is some cases, for instance if a hidden
539b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian    // or fully transparent window is updating.
540b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian    // in that case, we need to flip anyways to not risk a deadlock with
541b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian    // h/w composer.
542b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian
543a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
544a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    const nsecs_t now = systemTime();
545a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = now;
546a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    hw.flip(mSwapRegion);
547e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
548e8696a40e09b24b634214684d18526187b316a2fJamie Gennis    size_t numLayers = mVisibleLayersSortedByZ.size();
549ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall    HWComposer& hwc(graphicPlane(0).displayHardware().getHwComposer());
550ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall    if (hwc.initCheck() == NO_ERROR) {
551ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall        HWComposer::LayerListIterator cur = hwc.begin();
552ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall        const HWComposer::LayerListIterator end = hwc.end();
553ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall        for (size_t i = 0; cur != end && i < numLayers; ++i, ++cur) {
554ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall            mVisibleLayersSortedByZ[i]->onLayerDisplayed(&*cur);
555ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall        }
556ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall    } else {
557ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall        for (size_t i = 0; i < numLayers; i++) {
558ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall            mVisibleLayersSortedByZ[i]->onLayerDisplayed(NULL);
559ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall        }
560e8696a40e09b24b634214684d18526187b316a2fJamie Gennis    }
561e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
562a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mLastSwapBufferTime = systemTime() - now;
563a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = 0;
564a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mSwapRegion.clear();
565edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
566edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
567edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
568edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
569841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
570841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
571ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    Mutex::Autolock _l(mStateLock);
572ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    const nsecs_t now = systemTime();
573ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = now;
574ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
575ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // Here we're guaranteed that some transaction flags are set
576ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // so we can call handleTransactionLocked() unconditionally.
577ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // We call getTransactionFlags(), which will also clear the flags,
578ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // with mStateLock held to guarantee that mCurrentState won't change
579ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // until the transaction is committed.
580ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
581ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
582ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    transactionFlags = getTransactionFlags(mask);
583ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    handleTransactionLocked(transactionFlags);
584ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
585ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mLastTransactionTime = systemTime() - now;
586ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = 0;
587ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    invalidateHwcGeometry();
588ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // here the transaction has been committed
5893d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian}
590edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
591ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopianvoid SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
5923d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{
5933d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    const LayerVector& currentLayers(mCurrentState.layersSortedByZ);
594edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t count = currentLayers.size();
595edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
596edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
597edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Traversal of the children
598edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * (perform the transaction for each of them if needed)
599edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
600edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
601edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const bool layersNeedTransaction = transactionFlags & eTraversalNeeded;
602edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (layersNeedTransaction) {
603edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (size_t i=0 ; i<count ; i++) {
604076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            const sp<LayerBase>& layer = currentLayers[i];
605edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
606edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (!trFlags) continue;
607edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
608edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const uint32_t flags = layer->doTransaction(0);
609edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (flags & Layer::eVisibleRegion)
610edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mVisibleRegionsDirty = true;
611edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
612edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
613edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
614edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
615edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Perform our own transaction if needed
616edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
617edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
618edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (transactionFlags & eTransactionNeeded) {
619edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (mCurrentState.orientation != mDrawingState.orientation) {
620edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // the orientation has changed, recompute all visible regions
621edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // and invalidate everything.
622edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
623edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int dpy = 0;
624edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int orientation = mCurrentState.orientation;
62521230c6410bdab13cd2bd274da54b1e4061b6035Jeff Brown            // Currently unused: const uint32_t flags = mCurrentState.orientationFlags;
626edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            GraphicPlane& plane(graphicPlane(dpy));
627edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            plane.setOrientation(orientation);
628edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
629edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // update the shared control block
630edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const DisplayHardware& hw(plane.displayHardware());
631edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            volatile display_cblk_t* dcblk = mServerCblk->displays + dpy;
632edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dcblk->orientation = orientation;
6332b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            dcblk->w = plane.getWidth();
6342b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            dcblk->h = plane.getHeight();
635edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
636edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
637edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mDirtyRegion.set(hw.bounds());
638edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
639edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
6400aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        if (currentLayers.size() > mDrawingState.layersSortedByZ.size()) {
6410aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            // layers have been added
642edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
643edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
644edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
6450aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        // some layers might have been removed, so
6460aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        // we need to update the regions they're exposing.
6470aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        if (mLayersRemoved) {
64848d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian            mLayersRemoved = false;
649edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
6500aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            const LayerVector& previousLayers(mDrawingState.layersSortedByZ);
6513d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian            const size_t count = previousLayers.size();
6523d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian            for (size_t i=0 ; i<count ; i++) {
6530aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                const sp<LayerBase>& layer(previousLayers[i]);
6540aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                if (currentLayers.indexOf( layer ) < 0) {
6550aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                    // this layer is not visible anymore
6565d7126b625c8c4a7b945e8c247b63abff7bc13b6Mathias Agopian                    mDirtyRegionRemovedLayer.orSelf(layer->visibleRegionScreen);
6570aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                }
6580aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            }
659edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
660edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
661edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
662edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    commitTransaction();
663edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
664edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
665edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::computeVisibleRegions(
6661bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian    const LayerVector& currentLayers, Region& dirtyRegion, Region& opaqueRegion)
667edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
668841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
669841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
670edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(graphicPlane(0));
671edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Transform& planeTransform(plane.transform());
672ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian    const DisplayHardware& hw(plane.displayHardware());
673ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian    const Region screenRegion(hw.bounds());
674edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
675edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveOpaqueLayers;
676edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveCoveredLayers;
677edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region dirty;
678edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
679edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    bool secureFrameBuffer = false;
680edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
681edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t i = currentLayers.size();
682edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    while (i--) {
683076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        const sp<LayerBase>& layer = currentLayers[i];
684edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->validateVisibility(planeTransform);
685edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
686edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // start with the whole surface at its current location
687970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian        const Layer::State& s(layer->drawingState());
688edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
689ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
690ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * opaqueRegion: area of a surface that is fully opaque.
691ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
692edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region opaqueRegion;
693ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
694ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
695ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visibleRegion: area of a surface that is visible on screen
696ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * and not fully transparent. This is essentially the layer's
697ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * footprint minus the opaque regions above it.
698ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * Areas covered by a translucent surface are considered visible.
699ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
700edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region visibleRegion;
701ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
702ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
703ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * coveredRegion: area of a surface that is covered by all
704ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visible regions above it (which includes the translucent areas).
705ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
706edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region coveredRegion;
707ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
708ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
709ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // handle hidden surfaces by setting the visible region to empty
71099ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten        if (CC_LIKELY(!(s.flags & ISurfaceComposer::eLayerHidden) && s.alpha)) {
711a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            const bool translucent = !layer->isOpaque();
712970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian            const Rect bounds(layer->visibleBounds());
713edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            visibleRegion.set(bounds);
714ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            visibleRegion.andSelf(screenRegion);
715ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            if (!visibleRegion.isEmpty()) {
716ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // Remove the transparent area from the visible region
717ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (translucent) {
718ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    visibleRegion.subtractSelf(layer->transparentRegionScreen);
719ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
720edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
721ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // compute the opaque region
722ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                const int32_t layerOrientation = layer->getOrientation();
723ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (s.alpha==255 && !translucent &&
724ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                        ((layerOrientation & Transform::ROT_INVALID) == false)) {
725ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    // the opaque region is the layer's footprint
726ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    opaqueRegion = visibleRegion;
727ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
728edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
729edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
730edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
731ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Clip the covered region to the visible region
732ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        coveredRegion = aboveCoveredLayers.intersect(visibleRegion);
733ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
734ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveCoveredLayers for next (lower) layer
735ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        aboveCoveredLayers.orSelf(visibleRegion);
736ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
737edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // subtract the opaque region covered by the layers above us
738edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        visibleRegion.subtractSelf(aboveOpaqueLayers);
739edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
740edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // compute this layer's dirty region
741edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (layer->contentDirty) {
742edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // we need to invalidate the whole region
743edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dirty = visibleRegion;
744edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // as well, as the old visible region
745edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dirty.orSelf(layer->visibleRegionScreen);
746edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->contentDirty = false;
747edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
748a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian            /* compute the exposed region:
749ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   the exposed region consists of two components:
750ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   1) what's VISIBLE now and was COVERED before
751ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   2) what's EXPOSED now less what was EXPOSED before
752ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
753ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * note that (1) is conservative, we start with the whole
754ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * visible region but only keep what used to be covered by
755ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * something -- which mean it may have been exposed.
756ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
757ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * (2) handles areas that were not covered by anything but got
758ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * exposed because of a resize.
759a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian             */
760ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region newExposed = visibleRegion - coveredRegion;
761ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldVisibleRegion = layer->visibleRegionScreen;
762ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldCoveredRegion = layer->coveredRegionScreen;
763ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldExposed = oldVisibleRegion - oldCoveredRegion;
764ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed);
765edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
766edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirty.subtractSelf(aboveOpaqueLayers);
767edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
768edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // accumulate to the screen dirty region
769edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirtyRegion.orSelf(dirty);
770edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
771ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveOpaqueLayers for next (lower) layer
772edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        aboveOpaqueLayers.orSelf(opaqueRegion);
7738b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
774edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // Store the visible region is screen space
775edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setVisibleRegion(visibleRegion);
776edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setCoveredRegion(coveredRegion);
777edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
778970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian        // If a secure layer is partially visible, lock-down the screen!
779edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (layer->isSecure() && !visibleRegion.isEmpty()) {
780edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            secureFrameBuffer = true;
781edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
782edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
783edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
784970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian    // invalidate the areas where a layer was removed
785970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian    dirtyRegion.orSelf(mDirtyRegionRemovedLayer);
786970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian    mDirtyRegionRemovedLayer.clear();
787970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian
788edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mSecureFrameBuffer = secureFrameBuffer;
789edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    opaqueRegion = aboveOpaqueLayers;
790edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
791edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
792edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
793edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::commitTransaction()
794edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
7952f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall    if (!mLayersPendingRemoval.isEmpty()) {
7962f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall        // Notify removed layers now that they can't be drawn from
7972f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall        for (size_t i = 0; i < mLayersPendingRemoval.size(); i++) {
7982f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall            mLayersPendingRemoval[i]->onRemoved();
7992f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall        }
8002f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall        mLayersPendingRemoval.clear();
8012f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall    }
8022f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall
803edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDrawingState = mCurrentState;
80428378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    mTransationPending = false;
805cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mTransactionCV.broadcast();
806edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
807edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
808edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handlePageFlip()
809edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
8101c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
81199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    const DisplayHardware& hw = graphicPlane(0).displayHardware();
81299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    const Region screenRegion(hw.bounds());
81399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
8141bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian    const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
81599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    const bool visibleRegions = lockPageFlip(currentLayers);
816edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
81799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        if (visibleRegions || mVisibleRegionsDirty) {
818edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            Region opaqueRegion;
819edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            computeVisibleRegions(currentLayers, mDirtyRegion, opaqueRegion);
8204da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
8214da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            /*
8224da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian             *  rebuild the visible layer list
8234da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian             */
8241bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian            const size_t count = currentLayers.size();
8254da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            mVisibleLayersSortedByZ.clear();
8264da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            mVisibleLayersSortedByZ.setCapacity(count);
8274da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            for (size_t i=0 ; i<count ; i++) {
8284da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian                if (!currentLayers[i]->visibleRegionScreen.isEmpty())
8294da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian                    mVisibleLayersSortedByZ.add(currentLayers[i]);
8304da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            }
8314da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
832edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mWormholeRegion = screenRegion.subtract(opaqueRegion);
833edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = false;
834ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian            invalidateHwcGeometry();
835edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
836edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
837edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    unlockPageFlip(currentLayers);
8380dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian
8390dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    mDirtyRegion.orSelf(getAndClearInvalidateRegion());
840edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDirtyRegion.andSelf(screenRegion);
841edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
842edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
843ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopianvoid SurfaceFlinger::invalidateHwcGeometry()
844ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian{
845ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian    mHwWorkListDirty = true;
846ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian}
847ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian
848edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool SurfaceFlinger::lockPageFlip(const LayerVector& currentLayers)
849edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
850edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    bool recomputeVisibleRegions = false;
851edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t count = currentLayers.size();
852076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBase> const* layers = currentLayers.array();
853edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (size_t i=0 ; i<count ; i++) {
854b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
855edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->lockPageFlip(recomputeVisibleRegions);
856edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
857edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return recomputeVisibleRegions;
858edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
859edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
860edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::unlockPageFlip(const LayerVector& currentLayers)
861edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
862edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(graphicPlane(0));
863edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Transform& planeTransform(plane.transform());
86499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    const size_t count = currentLayers.size();
865076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBase> const* layers = currentLayers.array();
866edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (size_t i=0 ; i<count ; i++) {
867b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
868edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->unlockPageFlip(planeTransform, mDirtyRegion);
869edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
870edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
871edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
87299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::handleRefresh()
87399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
87499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    bool needInvalidate = false;
87599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
87699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    const size_t count = currentLayers.size();
87799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
87899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
87999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        if (layer->onPreComposition()) {
88099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            needInvalidate = true;
88199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        }
88299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    }
88399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    if (needInvalidate) {
88499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        signalLayerUpdate();
88599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    }
88699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
88799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
88899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
889a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopianvoid SurfaceFlinger::handleWorkList()
890a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian{
891a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    mHwWorkListDirty = false;
892a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    HWComposer& hwc(graphicPlane(0).displayHardware().getHwComposer());
893a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    if (hwc.initCheck() == NO_ERROR) {
894a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        const Vector< sp<LayerBase> >& currentLayers(mVisibleLayersSortedByZ);
895a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        const size_t count = currentLayers.size();
896a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        hwc.createWorkList(count);
8973e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian
8983e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian        HWComposer::LayerListIterator cur = hwc.begin();
8993e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian        const HWComposer::LayerListIterator end = hwc.end();
9003e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian        for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
9013e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian            currentLayers[i]->setGeometry(*cur);
90253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian            if (mDebugDisableHWC || mDebugRegion) {
9033e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian                cur->setSkip(true);
90473d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian            }
905a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        }
906a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
907a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian}
908b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian
909edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleRepaint()
910edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
911841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
912841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
913b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // compute the invalid region
9140656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian    mSwapRegion.orSelf(mDirtyRegion);
915edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
91699ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten    if (CC_UNLIKELY(mDebugRegion)) {
917edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        debugFlashRegions();
918edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
919edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
920b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // set the frame buffer
921b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
922b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    glMatrixMode(GL_MODELVIEW);
923b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    glLoadIdentity();
924edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
925edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t flags = hw.getFlags();
926a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian    if (flags & DisplayHardware::SWAP_RECTANGLE) {
92729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // we can redraw only what's dirty, but since SWAP_RECTANGLE only
92829d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // takes a rectangle, we must make sure to update that whole
92929d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // rectangle in that case
930a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        mDirtyRegion.set(mSwapRegion.bounds());
931edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
93295a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian        if (flags & DisplayHardware::PARTIAL_UPDATES) {
93329d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // We need to redraw the rectangle that will be updated
934df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian            // (pushed to the framebuffer).
93595a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian            // This is needed because PARTIAL_UPDATES only takes one
93629d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // rectangle instead of a region (see DisplayHardware::flip())
9370656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian            mDirtyRegion.set(mSwapRegion.bounds());
938edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
93929d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // we need to redraw everything (the whole screen)
940edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mDirtyRegion.set(hw.bounds());
9410656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian            mSwapRegion = mDirtyRegion;
942edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
943edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
944edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
945a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian    setupHardwareComposer();
946edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    composeSurfaces(mDirtyRegion);
947edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
9489c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    // update the swap region and clear the dirty region
9499c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    mSwapRegion.orSelf(mDirtyRegion);
950edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDirtyRegion.clear();
951edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
952edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
953a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopianvoid SurfaceFlinger::setupHardwareComposer()
954edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
955f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
956f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    HWComposer& hwc(hw.getHwComposer());
9573e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian
9583e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    HWComposer::LayerListIterator cur = hwc.begin();
9593e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    const HWComposer::LayerListIterator end = hwc.end();
9603e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    if (cur == end) {
9619c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        return;
962edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
963a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
9644da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian    const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
96545721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    size_t count = layers.size();
966a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
967e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block    ALOGE_IF(hwc.getNumLayers() != count,
96845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            "HAL number of layers (%d) doesn't match surfaceflinger (%d)",
96945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            hwc.getNumLayers(), count);
970a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
97145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    // just to be extra-safe, use the smallest count
97224925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling    if (hwc.initCheck() == NO_ERROR) {
97324925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling        count = count < hwc.getNumLayers() ? count : hwc.getNumLayers();
97424925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling    }
975a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
97645721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    /*
97745721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     *  update the per-frame h/w composer data for each layer
97845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     *  and build the transparent region of the FB
97945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     */
9803e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
981f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
9823e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian        layer->setPerFrameData(*cur);
983f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    }
984f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    status_t err = hwc.prepare();
985e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block    ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
986f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian}
987f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian
988f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopianvoid SurfaceFlinger::composeSurfaces(const Region& dirty)
989f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian{
990cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
991cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian    HWComposer& hwc(hw.getHwComposer());
9923e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    HWComposer::LayerListIterator cur = hwc.begin();
9933e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    const HWComposer::LayerListIterator end = hwc.end();
994cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian
995cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian    const size_t fbLayerCount = hwc.getLayerCount(HWC_FRAMEBUFFER);
9963e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    if (cur==end || fbLayerCount) {
997a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        // Never touch the framebuffer if we don't have any framebuffer layers
99845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian
999b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian        if (hwc.getLayerCount(HWC_OVERLAY)) {
1000b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // when using overlays, we assume a fully transparent framebuffer
1001b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // NOTE: we could reduce how much we need to clear, for instance
1002b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // remove where there are opaque FB layers. however, on some
1003b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // GPUs doing a "clean slate" glClear might be more efficient.
1004b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // We'll revisit later if needed.
1005b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            glClearColor(0, 0, 0, 0);
1006b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            glClear(GL_COLOR_BUFFER_BIT);
1007b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian        } else {
1008b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // screen is already cleared here
1009b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            if (!mWormholeRegion.isEmpty()) {
1010b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                // can happen with SurfaceView
1011b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                drawWormhole();
1012b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            }
1013a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        }
10144b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian
1015a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        /*
1016a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian         * and then, render the layers targeted at the framebuffer
1017a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian         */
10184b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian
1019a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
1020a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        const size_t count = layers.size();
10213e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian        for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
1022a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian            const sp<LayerBase>& layer(layers[i]);
1023a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian            const Region clip(dirty.intersect(layer->visibleRegionScreen));
1024a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian            if (!clip.isEmpty()) {
10253e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian                if (cur->getCompositionType() == HWC_OVERLAY) {
10263e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian                    if (i && (cur->getHints() & HWC_HINT_CLEAR_FB)
1027a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                            && layer->isOpaque()) {
1028b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                        // never clear the very first layer since we're
1029b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                        // guaranteed the FB is already cleared
1030a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                        layer->clearWithOpenGL(clip);
1031a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                    }
1032a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                    continue;
1033a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                }
1034a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                // render the layer
1035a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                layer->draw(clip);
10364b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian            }
10374b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian        }
10384b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian    }
1039edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1040edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1041edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::debugFlashRegions()
1042edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
10430a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
10440a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    const uint32_t flags = hw.getFlags();
104553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian    const int32_t height = hw.getHeight();
10460656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian    if (mSwapRegion.isEmpty()) {
104753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian        return;
104853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian    }
10490a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
1050a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian    if (!(flags & DisplayHardware::SWAP_RECTANGLE)) {
10510a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        const Region repaint((flags & DisplayHardware::PARTIAL_UPDATES) ?
10520a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian                mDirtyRegion.bounds() : hw.bounds());
10530a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        composeSurfaces(repaint);
10540a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    }
10550a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
1056c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_EXTERNAL_OES);
1057c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_2D);
1058edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_BLEND);
1059edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
10600926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    static int toggle = 0;
10610926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    toggle = 1 - toggle;
10620926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    if (toggle) {
10630a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        glColor4f(1, 0, 1, 1);
10640926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    } else {
10650a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        glColor4f(1, 1, 0, 1);
10660926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    }
1067edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
106820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    Region::const_iterator it = mDirtyRegion.begin();
106920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    Region::const_iterator const end = mDirtyRegion.end();
107020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    while (it != end) {
107120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        const Rect& r = *it++;
1072edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLfloat vertices[][2] = {
107353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.left,  height - r.top },
107453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.left,  height - r.bottom },
107553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.right, height - r.bottom },
107653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.right, height - r.top }
1077edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        };
1078edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glVertexPointer(2, GL_FLOAT, 0, vertices);
1079edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1080edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
10810a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
10820656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian    hw.flip(mSwapRegion);
1083edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1084edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mDebugRegion > 1)
10850a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        usleep(mDebugRegion * 1000);
1086edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1087edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1088edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::drawWormhole() const
1089edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1090edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Region region(mWormholeRegion.intersect(mDirtyRegion));
1091edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (region.isEmpty())
1092edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1093edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1094f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    glDisable(GL_TEXTURE_EXTERNAL_OES);
1095b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian    glDisable(GL_TEXTURE_2D);
1096f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    glDisable(GL_BLEND);
1097b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian    glColor4f(0,0,0,0);
1098f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian
1099f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    GLfloat vertices[4][2];
1100f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    glVertexPointer(2, GL_FLOAT, 0, vertices);
1101f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    Region::const_iterator it = region.begin();
1102f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    Region::const_iterator const end = region.end();
1103f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    while (it != end) {
1104f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        const Rect& r = *it++;
1105f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[0][0] = r.left;
1106f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[0][1] = r.top;
1107f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[1][0] = r.right;
1108f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[1][1] = r.top;
1109f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[2][0] = r.right;
1110f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[2][1] = r.bottom;
1111f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[3][0] = r.left;
1112f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[3][1] = r.bottom;
1113f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1114f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    }
1115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1117076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::addLayer(const sp<LayerBase>& layer)
1118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
1120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    addLayer_l(layer);
1121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
1122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1125076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::addLayer_l(const sp<LayerBase>& layer)
1126edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1127f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian    ssize_t i = mCurrentState.layersSortedByZ.add(layer);
11281b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    return (i < 0) ? status_t(i) : status_t(NO_ERROR);
11291b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian}
11301b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
113196f0819f81293076e652792794a961543e6750d7Mathias Agopianssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
113296f0819f81293076e652792794a961543e6750d7Mathias Agopian        const sp<LayerBaseClient>& lbc)
11331b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
113496f0819f81293076e652792794a961543e6750d7Mathias Agopian    // attach this layer to the client
11354f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    size_t name = client->attachLayer(lbc);
11364f113740180b6512b43723c4728f262882dc9b45Mathias Agopian
11374f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    Mutex::Autolock _l(mStateLock);
113896f0819f81293076e652792794a961543e6750d7Mathias Agopian
113996f0819f81293076e652792794a961543e6750d7Mathias Agopian    // add this layer to the current state list
114096f0819f81293076e652792794a961543e6750d7Mathias Agopian    addLayer_l(lbc);
114196f0819f81293076e652792794a961543e6750d7Mathias Agopian
11424f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    return ssize_t(name);
114396f0819f81293076e652792794a961543e6750d7Mathias Agopian}
114496f0819f81293076e652792794a961543e6750d7Mathias Agopian
114596f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer)
114696f0819f81293076e652792794a961543e6750d7Mathias Agopian{
114796f0819f81293076e652792794a961543e6750d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
114896f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = purgatorizeLayer_l(layer);
114996f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR)
115096f0819f81293076e652792794a961543e6750d7Mathias Agopian        setTransactionFlags(eTransactionNeeded);
115196f0819f81293076e652792794a961543e6750d7Mathias Agopian    return err;
1152edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1154076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase)
1155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1156b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<LayerBaseClient> lbc(layerBase->getLayerBaseClient());
1157b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (lbc != 0) {
11580d1561275e80073807ac04728951782d943f8882Mathias Agopian        mLayerMap.removeItem( lbc->getSurfaceBinder() );
1159b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    }
1160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase);
1161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (index >= 0) {
1162076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved = true;
1163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
1164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
11653d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    return status_t(index);
1166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
11689a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase)
11699a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
117076cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    // First add the layer to the purgatory list, which makes sure it won't
117176cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    // go away, then remove it from the main list (through a transaction).
11729a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    ssize_t err = removeLayer_l(layerBase);
117376cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    if (err >= 0) {
117476cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian        mLayerPurgatory.add(layerBase);
117576cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    }
11768c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian
11772f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall    mLayersPendingRemoval.push(layerBase);
11780b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian
11793d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // it's possible that we don't find a layer, because it might
11803d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // have been destroyed already -- this is not technically an error
118196f0819f81293076e652792794a961543e6750d7Mathias Agopian    // from the user because there is a race between Client::destroySurface(),
118296f0819f81293076e652792794a961543e6750d7Mathias Agopian    // ~Client() and ~ISurface().
11839a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err;
11849a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
11859a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
118696f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::invalidateLayerVisibility(const sp<LayerBase>& layer)
1187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
118896f0819f81293076e652792794a961543e6750d7Mathias Agopian    layer->forceVisibilityTransaction();
118996f0819f81293076e652792794a961543e6750d7Mathias Agopian    setTransactionFlags(eTraversalNeeded);
119096f0819f81293076e652792794a961543e6750d7Mathias Agopian    return NO_ERROR;
1191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1193dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopianuint32_t SurfaceFlinger::peekTransactionFlags(uint32_t flags)
1194dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian{
1195dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian    return android_atomic_release_load(&mTransactionFlags);
1196dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian}
1197dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian
1198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags)
1199edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1200edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return android_atomic_and(~flags, &mTransactionFlags) & flags;
1201edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1202edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1203bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags)
1204edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1205edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t old = android_atomic_or(flags, &mTransactionFlags);
1206edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((old & flags)==0) { // wake the server up
120799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        signalTransaction();
1208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1209edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return old;
1210edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1213b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennisvoid SurfaceFlinger::setTransactionState(const Vector<ComposerState>& state,
121428378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        int orientation, uint32_t flags) {
1215698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
1216cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
121728378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    uint32_t transactionFlags = 0;
1218b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis    if (mCurrentState.orientation != orientation) {
1219b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis        if (uint32_t(orientation)<=eOrientation270 || orientation==42) {
1220b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis            mCurrentState.orientation = orientation;
122128378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis            transactionFlags |= eTransactionNeeded;
1222b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis        } else if (orientation != eOrientationUnchanged) {
122332397c1cd3327905173b36baa6fd1c579bc328ffSteve Block            ALOGW("setTransactionState: ignoring unrecognized orientation: %d",
1224b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis                    orientation);
1225b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis        }
1226b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis    }
1227b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis
1228698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    const size_t count = state.size();
1229698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
1230698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const ComposerState& s(state[i]);
1231698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        sp<Client> client( static_cast<Client *>(s.client.get()) );
123228378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        transactionFlags |= setClientStateLocked(client, s.state);
1233698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    }
1234386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian
123528378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    if (transactionFlags) {
1236386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // this triggers the transaction
123728378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        setTransactionFlags(transactionFlags);
1238698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian
1239386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // if this is a synchronous transaction, wait for it to take effect
1240386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // before returning.
1241386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        if (flags & eSynchronous) {
1242386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            mTransationPending = true;
1243386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        }
1244386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        while (mTransationPending) {
1245386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
1246386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            if (CC_UNLIKELY(err != NO_ERROR)) {
1247386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                // just in case something goes wrong in SF, return to the
1248386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                // called after a few seconds.
124932397c1cd3327905173b36baa6fd1c579bc328ffSteve Block                ALOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!");
1250386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                mTransationPending = false;
1251386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                break;
1252386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            }
1253cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        }
1254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
12570ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopiansp<ISurface> SurfaceFlinger::createSurface(
12580ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        ISurfaceComposerClient::surface_data_t* params,
12590ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const String8& name,
12600ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const sp<Client>& client,
1261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        DisplayID d, uint32_t w, uint32_t h, PixelFormat format,
1262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t flags)
1263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1264076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBaseClient> layer;
1265a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    sp<ISurface> surfaceHandle;
12666e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian
12676e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    if (int32_t(w|h) < 0) {
1268e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE("createSurface() failed, w or h is negative (w=%d, h=%d)",
12696e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian                int(w), int(h));
12706e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian        return surfaceHandle;
12716e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    }
12728b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
1273ff615cc7a1cceedd705b0623b058c54669b29596Mathias Agopian    //ALOGD("createSurface for (%d x %d), name=%s", w, h, name.string());
1274b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<Layer> normalLayer;
1275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (flags & eFXSurfaceMask) {
1276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceNormal:
1277a5529c8778c2f407f482fc12165aeb76c0f505c2Mathias Agopian            normalLayer = createNormalSurface(client, d, w, h, flags, format);
1278a5529c8778c2f407f482fc12165aeb76c0f505c2Mathias Agopian            layer = normalLayer;
1279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
1280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceBlur:
12811293a8eb567fd63c072a6970fa9dcf37d076059fMathias Agopian            // for now we treat Blur as Dim, until we can implement it
12821293a8eb567fd63c072a6970fa9dcf37d076059fMathias Agopian            // efficiently.
1283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceDim:
128496f0819f81293076e652792794a961543e6750d7Mathias Agopian            layer = createDimSurface(client, d, w, h, flags);
1285edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
1286118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        case eFXSurfaceScreenshot:
1287118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian            layer = createScreenshotSurface(client, d, w, h, flags);
1288118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian            break;
1289edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1290edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1291076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (layer != 0) {
129296f0819f81293076e652792794a961543e6750d7Mathias Agopian        layer->initStates(w, h, flags);
1293285dbde2e0cd0057be070ded3be8f5f453147edcMathias Agopian        layer->setName(name);
129496f0819f81293076e652792794a961543e6750d7Mathias Agopian        ssize_t token = addClientLayer(client, layer);
1295b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        surfaceHandle = layer->getSurface();
12978b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber        if (surfaceHandle != 0) {
129896f0819f81293076e652792794a961543e6750d7Mathias Agopian            params->token = token;
1299a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            params->identity = layer->getIdentity();
1300b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            if (normalLayer != 0) {
1301b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian                Mutex::Autolock _l(mStateLock);
1302a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                mLayerMap.add(layer->getSurfaceBinder(), normalLayer);
1303b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            }
13041c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        }
1305b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
130696f0819f81293076e652792794a961543e6750d7Mathias Agopian        setTransactionFlags(eTransactionNeeded);
1307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return surfaceHandle;
1310edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1311edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1312b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<Layer> SurfaceFlinger::createNormalSurface(
1313f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        const sp<Client>& client, DisplayID display,
131496f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags,
13151c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        PixelFormat& format)
1316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize the surfaces
1318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (format) { // TODO: take h/w into account
1319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSPARENT:
1320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSLUCENT:
1321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        format = PIXEL_FORMAT_RGBA_8888;
1322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1323edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_OPAQUE:
1324a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888
1325a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian        format = PIXEL_FORMAT_RGB_565;
1326a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#else
13278f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian        format = PIXEL_FORMAT_RGBX_8888;
1328a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif
1329edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1330edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1331edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1332a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888
1333a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian    if (format == PIXEL_FORMAT_RGBX_8888)
1334a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian        format = PIXEL_FORMAT_RGBA_8888;
1335a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif
1336a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian
133796f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<Layer> layer = new Layer(this, display, client);
1338f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian    status_t err = layer->setBuffers(w, h, format, flags);
133999ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten    if (CC_LIKELY(err != NO_ERROR)) {
1340e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE("createNormalSurfaceLocked() failed (%s)", strerror(-err));
1341076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        layer.clear();
1342edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1343edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1344edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1345edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1346b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<LayerDim> SurfaceFlinger::createDimSurface(
1347f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        const sp<Client>& client, DisplayID display,
134896f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags)
1349edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
135096f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<LayerDim> layer = new LayerDim(this, display, client);
1351118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    return layer;
1352118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
1353118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
1354118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopiansp<LayerScreenshot> SurfaceFlinger::createScreenshotSurface(
1355118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        const sp<Client>& client, DisplayID display,
1356118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags)
1357118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{
1358118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    sp<LayerScreenshot> layer = new LayerScreenshot(this, display, client);
1359edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1360edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1361edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
136296f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeSurface(const sp<Client>& client, SurfaceID sid)
13639a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
13649a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    /*
13659a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     * called by the window manager, when a surface should be marked for
13669a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     * destruction.
13678b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber     *
13680aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * The surface is removed from the current and drawing lists, but placed
13690aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * in the purgatory queue, so it's not destroyed right-away (we need
13700aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * to wait for all client's references to go away first).
13719a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     */
13729a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
137348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    status_t err = NAME_NOT_FOUND;
13740aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian    Mutex::Autolock _l(mStateLock);
137596f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<LayerBaseClient> layer = client->getLayerUser(sid);
1376b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam
137748d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    if (layer != 0) {
137848d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        err = purgatorizeLayer_l(layer);
137948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        if (err == NO_ERROR) {
138048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian            setTransactionFlags(eTransactionNeeded);
138148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        }
13829a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    }
13839a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return err;
13849a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
13859a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
1386ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopianstatus_t SurfaceFlinger::destroySurface(const wp<LayerBaseClient>& layer)
1387edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1388759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian    // called by ~ISurface() when all references are gone
1389ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    status_t err = NO_ERROR;
1390ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    sp<LayerBaseClient> l(layer.promote());
1391ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    if (l != NULL) {
1392ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        Mutex::Autolock _l(mStateLock);
1393ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        err = removeLayer_l(l);
1394ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        if (err == NAME_NOT_FOUND) {
1395ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // The surface wasn't in the current list, which means it was
1396ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // removed already, which means it is in the purgatory,
1397ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // and need to be removed from there.
1398ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            ssize_t idx = mLayerPurgatory.remove(l);
1399e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block            ALOGE_IF(idx < 0,
1400ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian                    "layer=%p is not in the purgatory list", l.get());
1401f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        }
1402e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE_IF(err<0 && err != NAME_NOT_FOUND,
1403ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian                "error removing layer=%p (%s)", l.get(), strerror(-err));
1404ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    }
1405ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    return err;
1406edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1407edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1408698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopianuint32_t SurfaceFlinger::setClientStateLocked(
140996f0819f81293076e652792794a961543e6750d7Mathias Agopian        const sp<Client>& client,
1410698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const layer_state_t& s)
1411edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1412edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t flags = 0;
1413698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    sp<LayerBaseClient> layer(client->getLayerUser(s.surface));
1414698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    if (layer != 0) {
1415698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const uint32_t what = s.what;
1416698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & ePositionChanged) {
1417698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setPosition(s.x, s.y))
1418698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1419698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1420698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eLayerChanged) {
1421698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
1422698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setLayer(s.z)) {
1423698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                mCurrentState.layersSortedByZ.removeAt(idx);
1424698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                mCurrentState.layersSortedByZ.add(layer);
1425698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                // we need traversal (state changed)
1426698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                // AND transaction (list changed)
1427698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTransactionNeeded|eTraversalNeeded;
1428edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1429698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1430698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eSizeChanged) {
1431698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setSize(s.w, s.h)) {
1432698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1433edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1434edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1435698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eAlphaChanged) {
1436698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f)))
1437698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1438698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1439698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eMatrixChanged) {
1440698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setMatrix(s.matrix))
1441698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1442698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1443698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eTransparentRegionChanged) {
1444698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setTransparentRegionHint(s.transparentRegion))
1445698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1446698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1447698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eVisibilityChanged) {
1448698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setFlags(s.flags, s.mask))
1449698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1450698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1451f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        if (what & eCropChanged) {
1452f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis            if (layer->setCrop(s.crop))
1453f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis                flags |= eTraversalNeeded;
1454f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        }
1455edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1456698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    return flags;
1457edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1458edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1459b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// ---------------------------------------------------------------------------
1460b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
1461b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopianvoid SurfaceFlinger::onScreenAcquired() {
14628e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross    ALOGD("Screen about to return, flinger = %p", this);
1463b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
1464b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    hw.acquireScreen();
146522ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian    mEventThread->onScreenAcquired();
1466b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    // this is a temporary work-around, eventually this should be called
1467b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    // by the power-manager
1468b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    SurfaceFlinger::turnElectronBeamOn(mElectronBeamAnimationMode);
146922ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian    // from this point on, SF will process updates again
14708acce2046ac7086c3dcfb1fc7c9c39f31de48694Mathias Agopian    repaintEverything();
1471edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1472edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1473b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopianvoid SurfaceFlinger::onScreenReleased() {
14748e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross    ALOGD("About to give-up screen, flinger = %p", this);
1475b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
1476b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    if (hw.isScreenAcquired()) {
147722ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian        mEventThread->onScreenReleased();
1478b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        hw.releaseScreen();
1479b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        // from this point on, SF will stop drawing
1480b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    }
1481b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian}
1482b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
14838e533069e5721e55cb9768e140e16546c3a4a8b6Colin Crossvoid SurfaceFlinger::unblank() {
1484b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    class MessageScreenAcquired : public MessageBase {
1485b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        SurfaceFlinger* flinger;
1486b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    public:
1487b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        MessageScreenAcquired(SurfaceFlinger* flinger) : flinger(flinger) { }
1488b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        virtual bool handler() {
1489b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            flinger->onScreenAcquired();
1490b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            return true;
1491b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        }
1492b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    };
1493b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    sp<MessageBase> msg = new MessageScreenAcquired(this);
1494b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    postMessageSync(msg);
1495edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1496edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
14978e533069e5721e55cb9768e140e16546c3a4a8b6Colin Crossvoid SurfaceFlinger::blank() {
1498b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    class MessageScreenReleased : public MessageBase {
1499b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        SurfaceFlinger* flinger;
1500b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    public:
1501b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        MessageScreenReleased(SurfaceFlinger* flinger) : flinger(flinger) { }
1502b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        virtual bool handler() {
1503b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            flinger->onScreenReleased();
1504b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            return true;
1505b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        }
1506b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    };
1507b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    sp<MessageBase> msg = new MessageScreenReleased(this);
1508b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    postMessageSync(msg);
1509b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian}
1510b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
1511b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// ---------------------------------------------------------------------------
1512b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
1513edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
1514edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
15151d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling    const size_t SIZE = 4096;
1516edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char buffer[SIZE];
1517edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    String8 result;
151899b49840d309727678b77403d6cc9f920111623fMathias Agopian
151999b49840d309727678b77403d6cc9f920111623fMathias Agopian    if (!PermissionCache::checkCallingPermission(sDump)) {
1520edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        snprintf(buffer, SIZE, "Permission Denial: "
1521edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                "can't dump SurfaceFlinger from pid=%d, uid=%d\n",
1522edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                IPCThreadState::self()->getCallingPid(),
1523edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                IPCThreadState::self()->getCallingUid());
1524edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        result.append(buffer);
1525edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
15269795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // Try to get the main lock, but don't insist if we can't
15279795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // (this would indicate SF is stuck, but we want to be able to
15289795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // print something in dumpsys).
15299795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        int retry = 3;
15309795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        while (mStateLock.tryLock()<0 && --retry>=0) {
15319795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            usleep(1000000);
15329795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
15339795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const bool locked(retry >= 0);
15349795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (!locked) {
15358b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber            snprintf(buffer, SIZE,
15369795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "SurfaceFlinger appears to be unresponsive, "
15379795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "dumping anyways (no locks held)\n");
15389795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            result.append(buffer);
15399795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
15409795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
154182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        bool dumpAll = true;
154282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        size_t index = 0;
154325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        size_t numArgs = args.size();
154425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        if (numArgs) {
154525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
154625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--list"))) {
154725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                index++;
154825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                listLayersLocked(args, index, result, buffer, SIZE);
154935aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
155025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            }
155125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
155225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
155325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--latency"))) {
155482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                index++;
155582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                dumpStatsLocked(args, index, result, buffer, SIZE);
155635aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
155782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            }
155825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
155925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
156025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--latency-clear"))) {
156125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                index++;
156225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                clearStatsLocked(args, index, result, buffer, SIZE);
156335aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
156425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            }
1565edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
15661b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
156782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (dumpAll) {
156882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            dumpAllLocked(result, buffer, SIZE);
156982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
157048b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
157182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (locked) {
157282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mStateLock.unlock();
157348b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        }
157482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
157582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    write(fd, result.string(), result.size());
157682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    return NO_ERROR;
157782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
157848b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
157925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::listLayersLocked(const Vector<String16>& args, size_t& index,
158025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        String8& result, char* buffer, size_t SIZE) const
158125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
158225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
158325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const size_t count = currentLayers.size();
158425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
158525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
158625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        snprintf(buffer, SIZE, "%s\n", layer->getName().string());
158725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        result.append(buffer);
158825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
158925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
159025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
159182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index,
159282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        String8& result, char* buffer, size_t SIZE) const
159382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
159482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    String8 name;
159582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    if (index < args.size()) {
159682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        name = String8(args[index]);
159782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        index++;
159882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
159948b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
160082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
160182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const size_t count = currentLayers.size();
160282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    for (size_t i=0 ; i<count ; i++) {
160382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
160482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (name.isEmpty()) {
160582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            snprintf(buffer, SIZE, "%s\n", layer->getName().string());
160682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            result.append(buffer);
160782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
160882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (name.isEmpty() || (name == layer->getName())) {
160982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            layer->dumpStats(result, buffer, SIZE);
161082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
161182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
161282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
1613ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian
161425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& index,
161525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        String8& result, char* buffer, size_t SIZE) const
161625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
161725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    String8 name;
161825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    if (index < args.size()) {
161925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        name = String8(args[index]);
162025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        index++;
162125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
162225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
162325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
162425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const size_t count = currentLayers.size();
162525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
162625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
162725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        if (name.isEmpty() || (name == layer->getName())) {
162825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            layer->clearStats();
162925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        }
163025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
163125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
163225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
163382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpAllLocked(
163482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        String8& result, char* buffer, size_t SIZE) const
163582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
163682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    // figure out if we're stuck somewhere
163782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t now = systemTime();
163882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t inSwapBuffers(mDebugInSwapBuffers);
163982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t inTransaction(mDebugInTransaction);
164082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0;
164182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0;
1642bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
164382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
164482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump the visible layer list
164582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
164682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
164782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const size_t count = currentLayers.size();
164882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "Visible layers (count = %d)\n", count);
164982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
165082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    for (size_t i=0 ; i<count ; i++) {
165182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
165282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        layer->dump(result, buffer, SIZE);
165382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
1654bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
165582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
165682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump the layers in the purgatory
165782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
1658ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian
165982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const size_t purgatorySize = mLayerPurgatory.size();
166082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "Purgatory state (%d entries)\n", purgatorySize);
166182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
166282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    for (size_t i=0 ; i<purgatorySize ; i++) {
166382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
166482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        layer->shortDump(result, buffer, SIZE);
166582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
16661b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
166782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
166882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump SurfaceFlinger global state
166982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
16701b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
167182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "SurfaceFlinger global state:\n");
167282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
16731b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
167482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const GLExtensions& extensions(GLExtensions::getInstance());
167582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "GLES: %s, %s, %s\n",
167682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            extensions.getVendor(),
167782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            extensions.getRenderer(),
167882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            extensions.getVersion());
167982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
1680d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
168182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "EGL : %s\n",
168282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            eglQueryString(graphicPlane(0).getEGLDisplay(),
168382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                    EGL_VERSION_HW_ANDROID));
168482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
168573d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian
168682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "EXTS: %s\n", extensions.getExtension());
168782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
16889795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
168982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    mWormholeRegion.dump(result, "WormholeRegion");
169082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
169182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE,
169282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  orientation=%d, canDraw=%d\n",
169382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mCurrentState.orientation, hw.canDraw());
169482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
169582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE,
169682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  last eglSwapBuffers() time: %f us\n"
169782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  last transaction time     : %f us\n"
1698c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian            "  transaction-flags         : %08x\n"
169982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  refresh-rate              : %f fps\n"
170082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  x-dpi                     : %f\n"
1701b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian            "  y-dpi                     : %f\n"
1702b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian            "  density                   : %f\n",
170382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mLastSwapBufferTime/1000.0,
170482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mLastTransactionTime/1000.0,
1705c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian            mTransactionFlags,
170682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            hw.getRefreshRate(),
170782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            hw.getDpiX(),
1708b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian            hw.getDpiY(),
1709b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian            hw.getDensity());
171082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
171182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
171282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "  eglSwapBuffers time: %f us\n",
171382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            inSwapBuffersDuration/1000.0);
171482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
171582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
171682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "  transaction time: %f us\n",
171782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            inTransactionDuration/1000.0);
171882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
171982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
172082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
172182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * VSYNC state
172282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
172382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    mEventThread->dump(result, buffer, SIZE);
172482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
172582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
172682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump HWComposer state
172782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
172882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    HWComposer& hwc(hw.getHwComposer());
172982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "h/w composer state:\n");
173082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
173182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "  h/w composer %s and %s\n",
173282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            hwc.initCheck()==NO_ERROR ? "present" : "not present",
173382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                    (mDebugDisableHWC || mDebugRegion) ? "disabled" : "enabled");
173482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
173582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    hwc.dump(result, buffer, SIZE, mVisibleLayersSortedByZ);
173682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
173782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
173882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump gralloc state
173982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
174082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
174182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    alloc.dump(result);
174282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    hw.dump(result);
1743edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1744edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1745edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::onTransact(
1746edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
1747edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1748edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (code) {
1749edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case CREATE_CONNECTION:
1750698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        case SET_TRANSACTION_STATE:
1751edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case SET_ORIENTATION:
1752edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case BOOT_FINISHED:
175359119e658a12279e8fff508f8773843de2d90917Mathias Agopian        case TURN_ELECTRON_BEAM_OFF:
17549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        case TURN_ELECTRON_BEAM_ON:
17558e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross        case BLANK:
17568e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross        case UNBLANK:
1757edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        {
1758edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // codes that require permission check
1759edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            IPCThreadState* ipc = IPCThreadState::self();
1760edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int pid = ipc->getCallingPid();
1761a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian            const int uid = ipc->getCallingUid();
176299b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
176399b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) {
1764e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block                ALOGE("Permission Denial: "
1765375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                        "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
1766375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                return PERMISSION_DENIED;
1767edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
17681b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
17691b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
17701b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        case CAPTURE_SCREEN:
17711b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
17721b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            // codes that require permission check
17731b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
17741b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int pid = ipc->getCallingPid();
17751b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int uid = ipc->getCallingUid();
177699b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
177799b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) {
1778e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block                ALOGE("Permission Denial: "
17791b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                        "can't read framebuffer pid=%d, uid=%d", pid, uid);
17801b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                return PERMISSION_DENIED;
17811b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            }
17821b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
1783edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1784edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
17851b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
1786edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
1787edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
1788b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        CHECK_INTERFACE(ISurfaceComposer, data, reply);
178999ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten        if (CC_UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) {
1790375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
1791375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int pid = ipc->getCallingPid();
1792375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int uid = ipc->getCallingUid();
1793e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block            ALOGE("Permission Denial: "
1794375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                    "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
1795edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return PERMISSION_DENIED;
1796edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1797edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int n;
1798edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        switch (code) {
179901b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian            case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE
180035b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian            case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE
1801edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1802edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1002:  // SHOW_UPDATES
1803edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                n = data.readInt32();
1804edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDebugRegion = n ? n : (mDebugRegion ? 0 : 1);
180553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
180653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
1807edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1808edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1004:{ // repaint everything
180953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
1810cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
1811cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            }
1812cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            case 1005:{ // force transaction
1813cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
1814cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
1815edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
18164d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            case 1006:{ // send empty update
18174d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian                signalRefresh();
18184d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian                return NO_ERROR;
18194d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            }
182053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian            case 1008:  // toggle use of hw composer
182153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                n = data.readInt32();
182253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                mDebugDisableHWC = n ? 1 : 0;
182353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
182453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
182553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                return NO_ERROR;
1826a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian            case 1009:  // toggle use of transform hint
1827a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                n = data.readInt32();
1828a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                mDebugDisableTransformHint = n ? 1 : 0;
1829a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                invalidateHwcGeometry();
1830a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                repaintEverything();
1831a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                return NO_ERROR;
1832edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1010:  // interrogate.
183301b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian                reply->writeInt32(0);
1834edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(0);
1835edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(mDebugRegion);
1836b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                reply->writeInt32(0);
183712839bee29bdcc65731b4d42029cc59e2320c5c4Dianne Hackborn                reply->writeInt32(mDebugDisableHWC);
1838edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1839edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1013: {
1840edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                Mutex::Autolock _l(mStateLock);
1841edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                const DisplayHardware& hw(graphicPlane(0).displayHardware());
1842edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(hw.getPageFlipCount());
1843edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1844edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return NO_ERROR;
1845edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1846edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1847edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return err;
1848edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1849edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
185053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopianvoid SurfaceFlinger::repaintEverything() {
185153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
18520dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    const Rect bounds(hw.getBounds());
18530dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    setInvalidateRegion(Region(bounds));
185499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    signalTransaction();
185553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian}
185653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian
18570dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopianvoid SurfaceFlinger::setInvalidateRegion(const Region& reg) {
18580dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    Mutex::Autolock _l(mInvalidateLock);
18590dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    mInvalidateRegion = reg;
18600dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian}
18610dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian
18620dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias AgopianRegion SurfaceFlinger::getAndClearInvalidateRegion() {
18630dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    Mutex::Autolock _l(mInvalidateLock);
18640dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    Region reg(mInvalidateRegion);
18650dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    mInvalidateRegion.clear();
18660dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    return reg;
18670dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian}
18680dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian
186959119e658a12279e8fff508f8773843de2d90917Mathias Agopian// ---------------------------------------------------------------------------
187059119e658a12279e8fff508f8773843de2d90917Mathias Agopian
1871118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopianstatus_t SurfaceFlinger::renderScreenToTexture(DisplayID dpy,
1872118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        GLuint* textureName, GLfloat* uOut, GLfloat* vOut)
1873118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{
1874118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    Mutex::Autolock _l(mStateLock);
1875118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    return renderScreenToTextureLocked(dpy, textureName, uOut, vOut);
1876118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
1877118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
18789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::renderScreenToTextureLocked(DisplayID dpy,
18799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        GLuint* textureName, GLfloat* uOut, GLfloat* vOut)
188059119e658a12279e8fff508f8773843de2d90917Mathias Agopian{
188122ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian    ATRACE_CALL();
188222ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian
188359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
188459119e658a12279e8fff508f8773843de2d90917Mathias Agopian        return INVALID_OPERATION;
188559119e658a12279e8fff508f8773843de2d90917Mathias Agopian
188659119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // get screen geometry
188759119e658a12279e8fff508f8773843de2d90917Mathias Agopian    const DisplayHardware& hw(graphicPlane(dpy).displayHardware());
188859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    const uint32_t hw_w = hw.getWidth();
188959119e658a12279e8fff508f8773843de2d90917Mathias Agopian    const uint32_t hw_h = hw.getHeight();
189059119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLfloat u = 1;
189159119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLfloat v = 1;
189259119e658a12279e8fff508f8773843de2d90917Mathias Agopian
189359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // make sure to clear all GL error flags
189459119e658a12279e8fff508f8773843de2d90917Mathias Agopian    while ( glGetError() != GL_NO_ERROR ) ;
189559119e658a12279e8fff508f8773843de2d90917Mathias Agopian
189659119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // create a FBO
189759119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLuint name, tname;
189859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glGenTextures(1, &tname);
189959119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
1900a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1901a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
19029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
19039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            hw_w, hw_h, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
190459119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (glGetError() != GL_NO_ERROR) {
1905015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian        while ( glGetError() != GL_NO_ERROR ) ;
190659119e658a12279e8fff508f8773843de2d90917Mathias Agopian        GLint tw = (2 << (31 - clz(hw_w)));
190759119e658a12279e8fff508f8773843de2d90917Mathias Agopian        GLint th = (2 << (31 - clz(hw_h)));
19089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
19099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian                tw, th, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
191059119e658a12279e8fff508f8773843de2d90917Mathias Agopian        u = GLfloat(hw_w) / tw;
191159119e658a12279e8fff508f8773843de2d90917Mathias Agopian        v = GLfloat(hw_h) / th;
191259119e658a12279e8fff508f8773843de2d90917Mathias Agopian    }
191359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glGenFramebuffersOES(1, &name);
191459119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
19159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES,
19169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0);
191759119e658a12279e8fff508f8773843de2d90917Mathias Agopian
19189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // redraw the screen entirely...
1919c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_EXTERNAL_OES);
1920c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_2D);
19219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glClearColor(0,0,0,1);
19229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glClear(GL_COLOR_BUFFER_BIT);
1923a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glMatrixMode(GL_MODELVIEW);
1924a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glLoadIdentity();
19259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
19269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const size_t count = layers.size();
19279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (size_t i=0 ; i<count ; ++i) {
19289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
19299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        layer->drawForSreenShot();
19309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
193159119e658a12279e8fff508f8773843de2d90917Mathias Agopian
1932118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    hw.compositionComplete();
1933118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
19349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // back to main framebuffer
19359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
19369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDeleteFramebuffersOES(1, &name);
193759119e658a12279e8fff508f8773843de2d90917Mathias Agopian
19389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *textureName = tname;
19399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *uOut = u;
19409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *vOut = v;
19419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
19429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
194359119e658a12279e8fff508f8773843de2d90917Mathias Agopian
19449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// ---------------------------------------------------------------------------
194559119e658a12279e8fff508f8773843de2d90917Mathias Agopian
1946ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopianclass VSyncWaiter {
1947ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    DisplayEventReceiver::Event buffer[4];
1948ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    sp<Looper> looper;
1949ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    sp<IDisplayEventConnection> events;
1950ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    sp<BitTube> eventTube;
1951ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopianpublic:
1952ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    VSyncWaiter(const sp<EventThread>& eventThread) {
1953ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        looper = new Looper(true);
1954ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        events = eventThread->createEventConnection();
1955ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        eventTube = events->getDataChannel();
1956ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        looper->addFd(eventTube->getFd(), 0, ALOOPER_EVENT_INPUT, 0, 0);
1957ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        events->requestNextVsync();
1958ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    }
1959ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
1960ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    void wait() {
1961ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        ssize_t n;
1962ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
1963ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        looper->pollOnce(-1);
1964ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        // we don't handle any errors here, it doesn't matter
1965ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        // and we don't want to take the risk to get stuck.
1966ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
1967ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        // drain the events...
1968ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        while ((n = DisplayEventReceiver::getEvents(
1969ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian                eventTube, buffer, 4)) > 0) ;
1970ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
1971ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        events->requestNextVsync();
1972ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    }
1973ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian};
1974ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
19759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::electronBeamOffAnimationImplLocked()
19769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
19779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // get screen geometry
19789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
19799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_w = hw.getWidth();
19809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_h = hw.getHeight();
1981a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    const Region screenBounds(hw.getBounds());
198259119e658a12279e8fff508f8773843de2d90917Mathias Agopian
19839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat u, v;
19849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLuint tname;
1985118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    status_t result = renderScreenToTextureLocked(0, &tname, &u, &v);
19869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (result != NO_ERROR) {
19879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return result;
19889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
198959119e658a12279e8fff508f8773843de2d90917Mathias Agopian
19909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat vtx[8];
1991a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    const GLfloat texCoords[4][2] = { {0,0}, {0,v}, {u,v}, {u,0} };
19929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
19939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
19949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
19959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1996b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1997b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
19989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
19999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
20009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glVertexPointer(2, GL_FLOAT, 0, vtx);
20019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2002ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    /*
2003ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     * Texture coordinate mapping
2004ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *
2005ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *                 u
2006ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *    1 +----------+---+
2007ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |     |    |   |  image is inverted
2008ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |     V    |   |  w.r.t. the texture
2009ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *  1-v +----------+   |  coordinates
2010ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |              |
2011ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |              |
2012ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |              |
2013ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *    0 +--------------+
2014ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      0              1
2015ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *
2016ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     */
2017ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian
20189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class s_curve_interpolator {
20199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float nbFrames, s, v;
20209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
20219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        s_curve_interpolator(int nbFrames, float s)
20229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : nbFrames(1.0f / (nbFrames-1)), s(s),
20239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian          v(1.0f + expf(-s + 0.5f*s)) {
20249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
20259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float operator()(int f) {
20269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const float x = f * nbFrames;
20279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f;
20289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
20299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
20309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class v_stretch {
20329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
20339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
20349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        v_stretch(uint32_t hw_w, uint32_t hw_h)
20359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
20369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
20379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
20389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w + (hw_w * v);
20399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = hw_h - (hw_h * v);
20409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
20419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
2042ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[0] = x;         vtx[1] = y;
2043ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
2044ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
2045ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
20469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
20479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
20489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class h_stretch {
20509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
20519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
20529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        h_stretch(uint32_t hw_w, uint32_t hw_h)
20539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
205459119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
20559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
20569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w - (hw_w * v);
20579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = 1.0f;
20589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
20599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
2060ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[0] = x;         vtx[1] = y;
2061ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
2062ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
2063ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
20649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
20659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
20669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2067ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    VSyncWaiter vsync(mEventThread);
2068ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
20699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // the full animation is 24 frames
2070ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    char value[PROPERTY_VALUE_MAX];
2071ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    property_get("debug.sf.electron_frames", value, "24");
2072ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    int nbFrames = (atoi(value) + 1) >> 1;
2073ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    if (nbFrames <= 0) // just in case
2074ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian        nbFrames = 24;
2075ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian
20769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itr(nbFrames, 7.5f);
20779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itg(nbFrames, 8.0f);
20789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itb(nbFrames, 8.5f);
20799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    v_stretch vverts(hw_w, hw_h);
2081a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian
2082a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glMatrixMode(GL_TEXTURE);
2083a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glLoadIdentity();
2084a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glMatrixMode(GL_MODELVIEW);
2085a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glLoadIdentity();
2086a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian
20879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnable(GL_BLEND);
20889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBlendFunc(GL_ONE, GL_ONE);
20899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=0 ; i<nbFrames ; i++) {
20909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float x, y, w, h;
20919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vr = itr(i);
20929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vg = itg(i);
20939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vb = itb(i);
20949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2095ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        // wait for vsync
2096ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        vsync.wait();
2097ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
20989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // clear screen
20999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(1,1,1,1);
21009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
21019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glEnable(GL_TEXTURE_2D);
210259119e658a12279e8fff508f8773843de2d90917Mathias Agopian
21039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the red plane
21049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vr);
21059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(1,0,0,1);
21069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
21079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the green plane
21099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vg);
21109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,1,0,1);
21119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
21129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the blue plane
21149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vb);
21159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,0,1,1);
21169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
21179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the white highlight (we use the last vertices)
211959119e658a12279e8fff508f8773843de2d90917Mathias Agopian        glDisable(GL_TEXTURE_2D);
212059119e658a12279e8fff508f8773843de2d90917Mathias Agopian        glColorMask(1,1,1,1);
21219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColor4f(vg, vg, vg, 1);
21229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
21239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
21249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
21259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    h_stretch hverts(hw_w, hw_h);
21279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_BLEND);
21289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_TEXTURE_2D);
21299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
21309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=0 ; i<nbFrames ; i++) {
21319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float v = itg(i);
21329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hverts(vtx, v);
2133ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
2134ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        // wait for vsync
2135ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        vsync.wait();
2136ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
21379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
21389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColor4f(1-v, 1-v, 1-v, 1);
21399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
21409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
21419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
21429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
21449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
21459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDeleteTextures(1, &tname);
2146a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    glDisable(GL_TEXTURE_2D);
2147c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_BLEND);
21489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
21499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
21509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::electronBeamOnAnimationImplLocked()
21529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
21539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    status_t result = PERMISSION_DENIED;
21549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
21569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return INVALID_OPERATION;
21579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // get screen geometry
21609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
21619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_w = hw.getWidth();
21629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_h = hw.getHeight();
21639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const Region screenBounds(hw.bounds());
21649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat u, v;
21669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLuint tname;
21679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    result = renderScreenToTextureLocked(0, &tname, &u, &v);
21689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (result != NO_ERROR) {
21699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return result;
21709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
21719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat vtx[8];
21739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const GLfloat texCoords[4][2] = { {0,v}, {0,0}, {u,0}, {u,v} };
21749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
21759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
21769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
21779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2178b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2179b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
21809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
21819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
21829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glVertexPointer(2, GL_FLOAT, 0, vtx);
21839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class s_curve_interpolator {
21859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float nbFrames, s, v;
21869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
21879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        s_curve_interpolator(int nbFrames, float s)
21889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : nbFrames(1.0f / (nbFrames-1)), s(s),
21899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian          v(1.0f + expf(-s + 0.5f*s)) {
21909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
21919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float operator()(int f) {
21929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const float x = f * nbFrames;
21939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f;
21949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
21959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
21969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class v_stretch {
21989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
21999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
22009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        v_stretch(uint32_t hw_w, uint32_t hw_h)
22019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
220259119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
22039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
22049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w + (hw_w * v);
22059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = hw_h - (hw_h * v);
22069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
22079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
22089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[0] = x;         vtx[1] = y;
22099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
22109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
22119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
22129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
22139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
22149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class h_stretch {
22169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
22179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
22189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        h_stretch(uint32_t hw_w, uint32_t hw_h)
22199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
22209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
22219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
22229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w - (hw_w * v);
22239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = 1.0f;
22249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
22259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
22269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[0] = x;         vtx[1] = y;
22279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
22289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
22299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
22309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
22319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
22329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2233ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    VSyncWaiter vsync(mEventThread);
2234ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
2235a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian    // the full animation is 12 frames
2236a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian    int nbFrames = 8;
22379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itr(nbFrames, 7.5f);
22389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itg(nbFrames, 8.0f);
22399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itb(nbFrames, 8.5f);
22409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    h_stretch hverts(hw_w, hw_h);
22429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_BLEND);
22439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_TEXTURE_2D);
22449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
22459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=nbFrames-1 ; i>=0 ; i--) {
22469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float v = itg(i);
22479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hverts(vtx, v);
2248ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
2249ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        // wait for vsync
2250ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        vsync.wait();
2251ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
22529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
22539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColor4f(1-v, 1-v, 1-v, 1);
22549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
22559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
22569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
22579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2258a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian    nbFrames = 4;
22599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    v_stretch vverts(hw_w, hw_h);
22609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnable(GL_BLEND);
22619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBlendFunc(GL_ONE, GL_ONE);
22629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=nbFrames-1 ; i>=0 ; i--) {
22639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float x, y, w, h;
22649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vr = itr(i);
22659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vg = itg(i);
22669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vb = itb(i);
226759119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2268ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        // wait for vsync
2269ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        vsync.wait();
2270ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
22719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // clear screen
227259119e658a12279e8fff508f8773843de2d90917Mathias Agopian        glColorMask(1,1,1,1);
22739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
22749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glEnable(GL_TEXTURE_2D);
22759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the red plane
22779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vr);
22789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(1,0,0,1);
22799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
22809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the green plane
22829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vg);
22839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,1,0,1);
22849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
22859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the blue plane
22879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vb);
22889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,0,1,1);
22899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
22909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
229259119e658a12279e8fff508f8773843de2d90917Mathias Agopian    }
229359119e658a12279e8fff508f8773843de2d90917Mathias Agopian
22949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
22959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
229659119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glDeleteTextures(1, &tname);
2297a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    glDisable(GL_TEXTURE_2D);
2298c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_BLEND);
229959119e658a12279e8fff508f8773843de2d90917Mathias Agopian
23009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
23019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
23029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
23039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// ---------------------------------------------------------------------------
23049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2305abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOffImplLocked(int32_t mode)
23069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
230722ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian    ATRACE_CALL();
230822ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian
23099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    DisplayHardware& hw(graphicPlane(0).editDisplayHardware());
23109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (!hw.canDraw()) {
23119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // we're already off
23129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return NO_ERROR;
23139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
23147ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian
23157ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian    // turn off hwc while we're doing the animation
23167ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian    hw.getHwComposer().disable();
23177ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian    // and make sure to turn it back on (if needed) next time we compose
23187ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian    invalidateHwcGeometry();
23197ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian
2320abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    if (mode & ISurfaceComposer::eElectronBeamAnimationOff) {
2321abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        electronBeamOffAnimationImplLocked();
2322abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    }
2323abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian
2324abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    // always clear the whole screen at the end of the animation
2325abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    glClearColor(0,0,0,1);
2326abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    glClear(GL_COLOR_BUFFER_BIT);
2327abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    hw.flip( Region(hw.bounds()) );
2328abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian
2329015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian    return NO_ERROR;
233059119e658a12279e8fff508f8773843de2d90917Mathias Agopian}
233159119e658a12279e8fff508f8773843de2d90917Mathias Agopian
233259119e658a12279e8fff508f8773843de2d90917Mathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOff(int32_t mode)
233359119e658a12279e8fff508f8773843de2d90917Mathias Agopian{
233459119e658a12279e8fff508f8773843de2d90917Mathias Agopian    class MessageTurnElectronBeamOff : public MessageBase {
233559119e658a12279e8fff508f8773843de2d90917Mathias Agopian        SurfaceFlinger* flinger;
2336abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        int32_t mode;
233759119e658a12279e8fff508f8773843de2d90917Mathias Agopian        status_t result;
233859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    public:
2339abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        MessageTurnElectronBeamOff(SurfaceFlinger* flinger, int32_t mode)
2340abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            : flinger(flinger), mode(mode), result(PERMISSION_DENIED) {
234159119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
234259119e658a12279e8fff508f8773843de2d90917Mathias Agopian        status_t getResult() const {
234359119e658a12279e8fff508f8773843de2d90917Mathias Agopian            return result;
234459119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
234559119e658a12279e8fff508f8773843de2d90917Mathias Agopian        virtual bool handler() {
234659119e658a12279e8fff508f8773843de2d90917Mathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
2347abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            result = flinger->turnElectronBeamOffImplLocked(mode);
234859119e658a12279e8fff508f8773843de2d90917Mathias Agopian            return true;
234959119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
235059119e658a12279e8fff508f8773843de2d90917Mathias Agopian    };
235159119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2352abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    sp<MessageBase> msg = new MessageTurnElectronBeamOff(this, mode);
235359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    status_t res = postMessageSync(msg);
235459119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (res == NO_ERROR) {
235559119e658a12279e8fff508f8773843de2d90917Mathias Agopian        res = static_cast<MessageTurnElectronBeamOff*>( msg.get() )->getResult();
23569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
23579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // work-around: when the power-manager calls us we activate the
23589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // animation. eventually, the "on" animation will be called
23599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // by the power-manager itself
2360abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        mElectronBeamAnimationMode = mode;
236159119e658a12279e8fff508f8773843de2d90917Mathias Agopian    }
236259119e658a12279e8fff508f8773843de2d90917Mathias Agopian    return res;
236359119e658a12279e8fff508f8773843de2d90917Mathias Agopian}
236459119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2365edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
2366edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2367abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOnImplLocked(int32_t mode)
23689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
23699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    DisplayHardware& hw(graphicPlane(0).editDisplayHardware());
23709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (hw.canDraw()) {
23719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // we're already on
23729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return NO_ERROR;
23739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
2374abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    if (mode & ISurfaceComposer::eElectronBeamAnimationOn) {
2375abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        electronBeamOnAnimationImplLocked();
2376abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    }
2377a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian
2378a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian    // make sure to redraw the whole screen when the animation is done
2379a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian    mDirtyRegion.set(hw.bounds());
238099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    signalTransaction();
2381a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian
2382015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian    return NO_ERROR;
23839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
23849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
23859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOn(int32_t mode)
23869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
23879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class MessageTurnElectronBeamOn : public MessageBase {
23889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        SurfaceFlinger* flinger;
2389abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        int32_t mode;
23909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        status_t result;
23919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
2392abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        MessageTurnElectronBeamOn(SurfaceFlinger* flinger, int32_t mode)
2393abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            : flinger(flinger), mode(mode), result(PERMISSION_DENIED) {
23949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
23959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        status_t getResult() const {
23969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return result;
23979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
23989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        virtual bool handler() {
23999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
2400abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            result = flinger->turnElectronBeamOnImplLocked(mode);
24019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return true;
24029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
24039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
24049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2405abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    postMessageAsync( new MessageTurnElectronBeamOn(this, mode) );
24069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
24079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
24089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
24099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// ---------------------------------------------------------------------------
24109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
241174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopianstatus_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy,
241274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        sp<IMemoryHeap>* heap,
241374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t* w, uint32_t* h, PixelFormat* f,
2414bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t sw, uint32_t sh,
2415bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ, uint32_t maxLayerZ)
241674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{
2417fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian    ATRACE_CALL();
2418fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian
241974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    status_t result = PERMISSION_DENIED;
242074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
242174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // only one display supported for now
242299ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten    if (CC_UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
242374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return BAD_VALUE;
242474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
242574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
242674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return INVALID_OPERATION;
242774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
242874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // get screen geometry
242974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const DisplayHardware& hw(graphicPlane(dpy).displayHardware());
243074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const uint32_t hw_w = hw.getWidth();
243174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const uint32_t hw_h = hw.getHeight();
243274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
243374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    if ((sw > hw_w) || (sh > hw_h))
243474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return BAD_VALUE;
243574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
243674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    sw = (!sw) ? hw_w : sw;
243774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    sh = (!sh) ? hw_h : sh;
243874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const size_t size = sw * sh * 4;
243974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
24409d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block    //ALOGD("screenshot: sw=%d, sh=%d, minZ=%d, maxZ=%d",
24411c71a47a6db679a3212f0c99e14f330d6da500faMathias Agopian    //        sw, sh, minLayerZ, maxLayerZ);
2442c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
244374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // make sure to clear all GL error flags
244474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    while ( glGetError() != GL_NO_ERROR ) ;
244574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
244674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // create a FBO
244774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    GLuint name, tname;
244874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glGenRenderbuffersOES(1, &tname);
244974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindRenderbufferOES(GL_RENDERBUFFER_OES, tname);
245074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA8_OES, sw, sh);
2451fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian
245274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glGenFramebuffersOES(1, &name);
245374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
245474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES,
245574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, tname);
245674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
245774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
2458c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
245974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    if (status == GL_FRAMEBUFFER_COMPLETE_OES) {
246074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
246174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // invert everything, b/c glReadPixel() below will invert the FB
246274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glViewport(0, 0, sw, sh);
246374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_PROJECTION);
246474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glPushMatrix();
246574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glLoadIdentity();
2466ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian        glOrthof(0, hw_w, hw_h, 0, 0, 1);
246774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_MODELVIEW);
246874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
246974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // redraw the screen entirely...
247074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glClearColor(0,0,0,1);
247174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
2472f653b897a449e10d6cbfb6e0812f7b0bb02d6482Mathias Agopian
24739575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        const LayerVector& layers(mDrawingState.layersSortedByZ);
24749575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        const size_t count = layers.size();
247574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        for (size_t i=0 ; i<count ; ++i) {
247674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            const sp<LayerBase>& layer(layers[i]);
2477b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian            const uint32_t flags = layer->drawingState().flags;
2478b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian            if (!(flags & ISurfaceComposer::eLayerHidden)) {
2479b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                const uint32_t z = layer->drawingState().z;
2480b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                if (z >= minLayerZ && z <= maxLayerZ) {
2481b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                    layer->drawForSreenShot();
2482b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                }
2483bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian            }
248474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        }
248574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
248674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // check for errors and return screen capture
248774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        if (glGetError() != GL_NO_ERROR) {
248874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // error while rendering
248974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            result = INVALID_OPERATION;
249074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        } else {
249174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // allocate shared memory large enough to hold the
249274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // screen capture
249374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            sp<MemoryHeapBase> base(
249474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    new MemoryHeapBase(size, 0, "screen-capture") );
249574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            void* const ptr = base->getBase();
249674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            if (ptr) {
249774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                // capture the screen with glReadPixels()
2498fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian                ScopedTrace _t(ATRACE_TAG, "glReadPixels");
249974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                glReadPixels(0, 0, sw, sh, GL_RGBA, GL_UNSIGNED_BYTE, ptr);
250074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                if (glGetError() == GL_NO_ERROR) {
250174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *heap = base;
250274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *w = sw;
250374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *h = sh;
250474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *f = PIXEL_FORMAT_RGBA_8888;
250574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    result = NO_ERROR;
250674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                }
250774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            } else {
250874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                result = NO_MEMORY;
250974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            }
251074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        }
251174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glViewport(0, 0, hw_w, hw_h);
251274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_PROJECTION);
251374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glPopMatrix();
251474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_MODELVIEW);
251574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    } else {
251674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        result = BAD_VALUE;
251774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    }
251874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
251974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // release FBO resources
252074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
252174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glDeleteRenderbuffersOES(1, &tname);
252274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glDeleteFramebuffersOES(1, &name);
2523e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian
2524e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian    hw.compositionComplete();
2525e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian
25269d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block    // ALOGD("screenshot: result = %s", result<0 ? strerror(result) : "OK");
2527c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
252874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    return result;
252974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian}
253074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
253174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
25321b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopianstatus_t SurfaceFlinger::captureScreen(DisplayID dpy,
25331b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        sp<IMemoryHeap>* heap,
253474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t* width, uint32_t* height, PixelFormat* format,
2535bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t sw, uint32_t sh,
2536bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ, uint32_t maxLayerZ)
25371b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian{
25381b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    // only one display supported for now
253999ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten    if (CC_UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
25401b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        return BAD_VALUE;
25411b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
25421b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
25431b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        return INVALID_OPERATION;
25441b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
25451b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    class MessageCaptureScreen : public MessageBase {
25461b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        SurfaceFlinger* flinger;
25471b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        DisplayID dpy;
25481b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        sp<IMemoryHeap>* heap;
25491b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        uint32_t* w;
25501b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        uint32_t* h;
25511b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        PixelFormat* f;
255274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t sw;
255374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t sh;
2554bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ;
2555bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t maxLayerZ;
25561b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        status_t result;
25571b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    public:
25581b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        MessageCaptureScreen(SurfaceFlinger* flinger, DisplayID dpy,
255974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                sp<IMemoryHeap>* heap, uint32_t* w, uint32_t* h, PixelFormat* f,
2560bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                uint32_t sw, uint32_t sh,
2561bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                uint32_t minLayerZ, uint32_t maxLayerZ)
25621b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            : flinger(flinger), dpy(dpy),
2563bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              heap(heap), w(w), h(h), f(f), sw(sw), sh(sh),
2564bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              minLayerZ(minLayerZ), maxLayerZ(maxLayerZ),
2565bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              result(PERMISSION_DENIED)
25661b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
25671b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
25681b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        status_t getResult() const {
25691b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            return result;
25701b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
25711b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        virtual bool handler() {
25721b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
25731b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
25741b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            // if we have secure windows, never allow the screen capture
25751b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            if (flinger->mSecureFrameBuffer)
25761b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                return true;
25771b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
257874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            result = flinger->captureScreenImplLocked(dpy,
2579bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                    heap, w, h, f, sw, sh, minLayerZ, maxLayerZ);
25801b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
25811b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            return true;
25821b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
25831b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    };
25841b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
25851b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    sp<MessageBase> msg = new MessageCaptureScreen(this,
2586bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian            dpy, heap, width, height, format, sw, sh, minLayerZ, maxLayerZ);
25871b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    status_t res = postMessageSync(msg);
25881b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    if (res == NO_ERROR) {
25891b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        res = static_cast<MessageCaptureScreen*>( msg.get() )->getResult();
25901b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    }
25911b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    return res;
25921b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian}
25931b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
25941b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// ---------------------------------------------------------------------------
25951b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
2596b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<Layer> SurfaceFlinger::getLayer(const sp<ISurface>& sur) const
2597edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2598b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<Layer> result;
2599b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    Mutex::Autolock _l(mStateLock);
2600b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    result = mLayerMap.valueFor( sur->asBinder() ).promote();
2601b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return result;
2602b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
26037303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
2604b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// ---------------------------------------------------------------------------
260596f0819f81293076e652792794a961543e6750d7Mathias Agopian
26069a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::GraphicBufferAlloc() {}
26079a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
26089a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::~GraphicBufferAlloc() {}
26099a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
26109a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h,
2611d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        PixelFormat format, uint32_t usage, status_t* error) {
26129a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(w, h, format, usage));
26139a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    status_t err = graphicBuffer->initCheck();
2614d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian    *error = err;
2615a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (err != 0 || graphicBuffer->handle == 0) {
2616d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        if (err == NO_MEMORY) {
2617d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian            GraphicBuffer::dumpAllocationsToSystemLog();
2618d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        }
2619e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE("GraphicBufferAlloc::createGraphicBuffer(w=%d, h=%d) "
2620a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian             "failed (%s), handle=%p",
2621a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                w, h, strerror(-err), graphicBuffer->handle);
26229a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis        return 0;
26239a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    }
26249a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    return graphicBuffer;
26259a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis}
26269a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
26279a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis// ---------------------------------------------------------------------------
26289a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
2629edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane::GraphicPlane()
2630edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    : mHw(0)
2631edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2632edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2633edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2634edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane::~GraphicPlane() {
2635edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    delete mHw;
2636edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2637edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2638edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool GraphicPlane::initialized() const {
2639edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return mHw ? true : false;
2640edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2641edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
26422b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianint GraphicPlane::getWidth() const {
26432b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    return mWidth;
2644edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2645edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
26462b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianint GraphicPlane::getHeight() const {
26472b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    return mHeight;
26482b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian}
26492b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
26502b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianvoid GraphicPlane::setDisplayHardware(DisplayHardware *hw)
26512b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian{
26522b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mHw = hw;
26532b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
26542b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    // initialize the display orientation transform.
26552b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    // it's a constant that should come from the display driver.
26562b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    int displayOrientation = ISurfaceComposer::eOrientationDefault;
26572b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    char property[PROPERTY_VALUE_MAX];
26582b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    if (property_get("ro.sf.hwrotation", property, NULL) > 0) {
26592b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        //displayOrientation
26602b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        switch (atoi(property)) {
26612b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        case 90:
26622b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            displayOrientation = ISurfaceComposer::eOrientation90;
26632b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            break;
26642b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        case 270:
26652b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            displayOrientation = ISurfaceComposer::eOrientation270;
26662b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            break;
26672b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        }
26682b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    }
26692b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
26702b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float w = hw->getWidth();
26712b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float h = hw->getHeight();
26722b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    GraphicPlane::orientationToTransfrom(displayOrientation, w, h,
26732b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            &mDisplayTransform);
26742b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    if (displayOrientation & ISurfaceComposer::eOrientationSwapMask) {
26752b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayWidth = h;
26762b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayHeight = w;
26772b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    } else {
26782b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayWidth = w;
26792b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayHeight = h;
26802b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    }
26812b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
26822b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    setOrientation(ISurfaceComposer::eOrientationDefault);
2683edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2684edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2685edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t GraphicPlane::orientationToTransfrom(
2686edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int orientation, int w, int h, Transform* tr)
2687eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian{
2688eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    uint32_t flags = 0;
2689edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (orientation) {
2690edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientationDefault:
2691eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_0;
2692eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        break;
2693edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientation90:
2694eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_90;
2695edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
2696edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientation180:
2697eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_180;
2698edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
2699edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientation270:
2700eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_270;
2701edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
2702edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    default:
2703edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return BAD_VALUE;
2704edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2705eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    tr->set(flags, w, h);
2706edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
2707edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2708edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2709edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t GraphicPlane::setOrientation(int orientation)
2710edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2711edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // If the rotation can be handled in hardware, this is where
2712edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // the magic should happen.
27132b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
27142b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const DisplayHardware& hw(displayHardware());
27152b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float w = mDisplayWidth;
27162b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float h = mDisplayHeight;
27172b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mWidth = int(w);
27182b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mHeight = int(h);
27192b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
27202b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    Transform orientationTransform;
2721eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    GraphicPlane::orientationToTransfrom(orientation, w, h,
2722eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian            &orientationTransform);
2723eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    if (orientation & ISurfaceComposer::eOrientationSwapMask) {
2724eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        mWidth = int(h);
2725eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        mHeight = int(w);
2726edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2727eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian
27280d1318b974feba2e6ff13e36a1781343c2fce045Mathias Agopian    mOrientation = orientation;
27292b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mGlobalTransform = mDisplayTransform * orientationTransform;
2730edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
2731edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2732edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2733edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst DisplayHardware& GraphicPlane::displayHardware() const {
2734edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return *mHw;
2735edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2736edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
273759119e658a12279e8fff508f8773843de2d90917Mathias AgopianDisplayHardware& GraphicPlane::editDisplayHardware() {
273859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    return *mHw;
273959119e658a12279e8fff508f8773843de2d90917Mathias Agopian}
274059119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2741edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst Transform& GraphicPlane::transform() const {
2742edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return mGlobalTransform;
2743edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2744edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2745076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias AgopianEGLDisplay GraphicPlane::getEGLDisplay() const {
2746076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return mHw->getEGLDisplay();
2747076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
2748076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
2749edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
2750edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2751edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
2752