SurfaceFlinger.cpp revision 1b03149f3533db04e72e088d3fdd09d0087ca594
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"
531b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian#include "DisplayHardware.h"
54db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian#include "Client.h"
55d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian#include "EventThread.h"
561f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian#include "GLExtensions.h"
57edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h"
58edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerDim.h"
59118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian#include "LayerScreenshot.h"
60edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h"
61edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
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 Projectvoid SurfaceFlinger::bootFinished()
182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t now = systemTime();
184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t duration = now - mBootTime;
185a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
1863330b203039dea366d4981db1408a460134b2d2cMathias Agopian    mBootFinished = true;
1871f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
1881f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // wait patiently for the window manager death
1891f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    const String16 name("window");
1901f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    sp<IBinder> window(defaultServiceManager()->getService(name));
1911f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    if (window != 0) {
1921f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian        window->linkToDeath(this);
1931f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    }
1941f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
1951f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // stop boot animation
196a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // formerly we would just kill the process, but we now ask it to exit so it
197a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // can choose where to stop the animation.
198a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("service.bootanim.exit", "1");
199edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
200edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
201edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic inline uint16_t pack565(int r, int g, int b) {
202edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return (r<<11)|(g<<5)|b;
203edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
204edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
205edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::readyToRun()
206edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2071b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    ALOGI(  "SurfaceFlinger's main thread ready to run. "
208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            "Initializing graphics H/W...");
209edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
210edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // we only support one display currently
211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int dpy = 0;
212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    {
214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // initialize the main display
2151b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian        // TODO: initialize all displays
216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        DisplayHardware* const hw = new DisplayHardware(this, dpy);
2171b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian        mDisplayHardwares[0] = hw;
218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2207303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    // create the shared control-block
2217303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    mServerHeap = new MemoryHeapBase(4096,
2227303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian            MemoryHeapBase::READ_ONLY, "SurfaceFlinger read-only heap");
223e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block    ALOGE_IF(mServerHeap==0, "can't create shared memory dealer");
2248b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
2257303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    mServerCblk = static_cast<surface_flinger_cblk_t*>(mServerHeap->getBase());
226e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block    ALOGE_IF(mServerCblk==0, "can't get to shared control block's address");
2278b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
2287303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    new(mServerCblk) surface_flinger_cblk_t;
2297303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize primary screen
231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // (other display should be initialized in the same manner, but
232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // asynchronously, as they could come and go. None of this is supported
233edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // yet).
2341b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    const DisplayHardware& hw(getDefaultDisplayHardware());
235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint32_t w = hw.getWidth();
236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint32_t h = hw.getHeight();
237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint32_t f = hw.getFormat();
238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    hw.makeCurrent();
239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize the shared control block
241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mServerCblk->connected |= 1<<dpy;
242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    display_cblk_t* dcblk = mServerCblk->displays + dpy;
243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    memset(dcblk, 0, sizeof(display_cblk_t));
2441b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    dcblk->w            = w; // XXX: plane.getWidth();
2451b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    dcblk->h            = h; // XXX: plane.getHeight();
246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->format       = f;
247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->orientation  = ISurfaceComposer::eOrientationDefault;
248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->xdpi         = hw.getDpiX();
249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->ydpi         = hw.getDpiY();
250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->fps          = hw.getRefreshRate();
251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->density      = hw.getDensity();
252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // Initialize OpenGL|ES
254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
2558b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber    glPixelStorei(GL_PACK_ALIGNMENT, 4);
256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glEnableClientState(GL_VERTEX_ARRAY);
257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glShadeModel(GL_FLAT);
258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_DITHER);
259edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_CULL_FACE);
260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint16_t g0 = pack565(0x0F,0x1F,0x0F);
262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint16_t g1 = pack565(0x17,0x2f,0x17);
2639575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    const uint16_t wormholeTexData[4] = { g0, g1, g1, g0 };
264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glGenTextures(1, &mWormholeTexName);
265edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glBindTexture(GL_TEXTURE_2D, mWormholeTexName);
266edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
267edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
269edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0,
2719575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis            GL_RGB, GL_UNSIGNED_SHORT_5_6_5, wormholeTexData);
2729575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis
2739575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    const uint16_t protTexData[] = { pack565(0x03, 0x03, 0x03) };
2749575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glGenTextures(1, &mProtectedTexName);
2759575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glBindTexture(GL_TEXTURE_2D, mProtectedTexName);
2769575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2779575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2789575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
2799575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
2809575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0,
2819575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis            GL_RGB, GL_UNSIGNED_SHORT_5_6_5, protTexData);
282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glViewport(0, 0, w, h);
284edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glMatrixMode(GL_PROJECTION);
285edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glLoadIdentity();
286ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    // put the origin in the left-bottom corner
287ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    glOrthof(0, w, 0, h, 0, 1); // l=0, r=w ; b=0, t=h
288edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
289d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
290d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian    // start the EventThread
291d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian    mEventThread = new EventThread(this);
2928aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian    mEventQueue.setEventThread(mEventThread);
293edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
294edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
295edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     *  We're now ready to accept clients...
296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
298d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian    mReadyToRunBarrier.open();
299d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
300a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    // start boot animation
301a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    startBootAnim();
3028b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
306a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopianvoid SurfaceFlinger::startBootAnim() {
307a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // start boot animation
308a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("service.bootanim.exit", "0");
309a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("ctl.start", "bootanim");
310a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian}
311a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian
312edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
313d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
314582270d69db94286a248bd829f1ae6f910d45124Jamie Gennisbool SurfaceFlinger::authenticateSurfaceTexture(
315582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis        const sp<ISurfaceTexture>& surfaceTexture) const {
316134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    Mutex::Autolock _l(mStateLock);
317582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis    sp<IBinder> surfaceTextureBinder(surfaceTexture->asBinder());
318134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
319134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // Check the visible layer list for the ISurface
320134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
321134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    size_t count = currentLayers.size();
322134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    for (size_t i=0 ; i<count ; i++) {
323134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        const sp<LayerBase>& layer(currentLayers[i]);
324134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        sp<LayerBaseClient> lbc(layer->getLayerBaseClient());
325582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis        if (lbc != NULL) {
326582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder();
327582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            if (lbcBinder == surfaceTextureBinder) {
328582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis                return true;
329582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            }
330134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        }
331134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    }
332134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
333134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // Check the layers in the purgatory.  This check is here so that if a
334582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis    // SurfaceTexture gets destroyed before all the clients are done using it,
335582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis    // the error will not be reported as "surface XYZ is not authenticated", but
336134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // will instead fail later on when the client tries to use the surface,
337134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // which should be reported as "surface XYZ returned an -ENODEV".  The
338134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // purgatorized layers are no less authentic than the visible ones, so this
339134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // should not cause any harm.
340134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    size_t purgatorySize =  mLayerPurgatory.size();
341134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    for (size_t i=0 ; i<purgatorySize ; i++) {
342134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
343134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        sp<LayerBaseClient> lbc(layer->getLayerBaseClient());
344582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis        if (lbc != NULL) {
345582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder();
346582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            if (lbcBinder == surfaceTextureBinder) {
347582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis                return true;
348582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            }
349134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        }
350134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    }
351134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
352134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    return false;
353134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis}
354134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
355d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian// ----------------------------------------------------------------------------
356d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
357d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopiansp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection() {
3588aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian    return mEventThread->createEventConnection();
359bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian}
360bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
3613094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopianvoid SurfaceFlinger::connectDisplay(const sp<ISurfaceTexture> display) {
3621b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    const DisplayHardware& hw(getDefaultDisplayHardware());
3633094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    EGLSurface result = EGL_NO_SURFACE;
3643094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    EGLSurface old_surface = EGL_NO_SURFACE;
3653094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    sp<SurfaceTextureClient> stc;
3663094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
3673094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    if (display != NULL) {
3683094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        stc = new SurfaceTextureClient(display);
3693094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        result = eglCreateWindowSurface(hw.getEGLDisplay(),
3703094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                hw.getEGLConfig(), (EGLNativeWindowType)stc.get(), NULL);
3713094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        ALOGE_IF(result == EGL_NO_SURFACE,
3723094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                "eglCreateWindowSurface failed (ISurfaceTexture=%p)",
3733094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                display.get());
3743094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    }
3753094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
3763094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    { // scope for the lock
3773094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        Mutex::Autolock _l(mStateLock);
3783094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        old_surface = mExternalDisplaySurface;
3793094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        mExternalDisplayNativeWindow = stc;
3803094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        mExternalDisplaySurface = result;
3813094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        ALOGD("mExternalDisplaySurface = %p", result);
3823094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    }
3833094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
3843094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    if (old_surface != EGL_NO_SURFACE) {
3853094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        // Note: EGL allows to destroy an object while its current
3863094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        // it will fail to become current next time though.
3873094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        eglDestroySurface(hw.getEGLDisplay(), old_surface);
3883094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    }
3893094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian}
3903094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
3913094df359d1e6e2ae8ca4e935cc093f563804c96Mathias AgopianEGLSurface SurfaceFlinger::getExternalDisplaySurface() const {
3923094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    Mutex::Autolock _l(mStateLock);
3933094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    return mExternalDisplaySurface;
3943094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian}
3953094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
396edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
39799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
39899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::waitForEvent() {
39999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.waitMessage();
40099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
40199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
40299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalTransaction() {
40399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.invalidate();
40499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
40599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
40699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalLayerUpdate() {
40799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.invalidate();
40899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
40999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
41099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalRefresh() {
41199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.refresh();
41299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
41399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
41499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg,
41599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        nsecs_t reltime, uint32_t flags) {
41699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return mEventQueue.postMessage(msg, reltime);
41799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
41899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
41999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,
42099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        nsecs_t reltime, uint32_t flags) {
42199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    status_t res = mEventQueue.postMessage(msg, reltime);
42299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    if (res == NO_ERROR) {
42399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        msg->wait();
42499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    }
42599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return res;
42699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
427edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
428edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool SurfaceFlinger::threadLoop()
429edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
430edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    waitForEvent();
43199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return true;
43299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
433edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
43499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::onMessageReceived(int32_t what)
43599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
4361c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
43799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    switch (what) {
43869a655caef30663403802281210363f643ceb946Mathias Agopian        case MessageQueue::REFRESH: {
43969a655caef30663403802281210363f643ceb946Mathias Agopian//        case MessageQueue::INVALIDATE: {
44099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            // if we're in a global transaction, don't do anything.
44199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
44299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            uint32_t transactionFlags = peekTransactionFlags(mask);
44399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            if (CC_UNLIKELY(transactionFlags)) {
44499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian                handleTransaction(transactionFlags);
44599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            }
446edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
44799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            // post surfaces (if needed)
44899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            handlePageFlip();
449edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
45069a655caef30663403802281210363f643ceb946Mathias Agopian//            signalRefresh();
45169a655caef30663403802281210363f643ceb946Mathias Agopian//
45269a655caef30663403802281210363f643ceb946Mathias Agopian//        } break;
45369a655caef30663403802281210363f643ceb946Mathias Agopian//
45469a655caef30663403802281210363f643ceb946Mathias Agopian//        case MessageQueue::REFRESH: {
4553a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian
456c9ca7011501cb8730ce4e6e527cb402adb7a0178Mathias Agopian            handleRefresh();
457a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
4581b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian            // TODO: iterate through all displays
4591b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian            const DisplayHardware& hw(getDisplayHardware(0));
460303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian
46169a655caef30663403802281210363f643ceb946Mathias Agopian//            if (mDirtyRegion.isEmpty()) {
46269a655caef30663403802281210363f643ceb946Mathias Agopian//                return;
46369a655caef30663403802281210363f643ceb946Mathias Agopian//            }
46469a655caef30663403802281210363f643ceb946Mathias Agopian
465b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian            if (CC_UNLIKELY(mHwWorkListDirty)) {
466b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian                // build the h/w work list
4671b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian                handleWorkList(hw);
468b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian            }
469303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian
470b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian            if (CC_LIKELY(hw.canDraw())) {
471b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian                // repaint the framebuffer (if needed)
4721b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian                handleRepaint(hw);
473b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian                // inform the h/w that we're done compositing
474b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian                hw.compositionComplete();
475b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian                postFramebuffer();
476c9ca7011501cb8730ce4e6e527cb402adb7a0178Mathias Agopian            } else {
477b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian                // pretend we did the post
478c9ca7011501cb8730ce4e6e527cb402adb7a0178Mathias Agopian                hw.compositionComplete();
47999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            }
480b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian
4813094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian            // render to the external display if we have one
4823094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian            EGLSurface externalDisplaySurface = getExternalDisplaySurface();
4833094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian            if (externalDisplaySurface != EGL_NO_SURFACE) {
4843094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                EGLSurface cur = eglGetCurrentSurface(EGL_DRAW);
4853094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                EGLBoolean success = eglMakeCurrent(eglGetCurrentDisplay(),
4863094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                        externalDisplaySurface, externalDisplaySurface,
4873094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                        eglGetCurrentContext());
4883094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
4893094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                ALOGE_IF(!success, "eglMakeCurrent -> external failed");
4903094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
4913094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                if (success) {
4923094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                    // redraw the screen entirely...
4933094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                    glDisable(GL_TEXTURE_EXTERNAL_OES);
4943094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                    glDisable(GL_TEXTURE_2D);
4953094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                    glClearColor(0,0,0,1);
4963094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                    glClear(GL_COLOR_BUFFER_BIT);
4973094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                    glMatrixMode(GL_MODELVIEW);
4983094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                    glLoadIdentity();
4993094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                    const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
5003094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                    const size_t count = layers.size();
5013094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                    for (size_t i=0 ; i<count ; ++i) {
5023094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                        const sp<LayerBase>& layer(layers[i]);
5031b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian                        layer->drawForSreenShot(hw);
5043094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                    }
5053094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
5063094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                    success = eglSwapBuffers(eglGetCurrentDisplay(), externalDisplaySurface);
5073094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                    ALOGE_IF(!success, "external display eglSwapBuffers failed");
5083094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
5093094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                    hw.compositionComplete();
5103094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                }
5113094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
5123094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                success = eglMakeCurrent(eglGetCurrentDisplay(),
5133094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                        cur, cur, eglGetCurrentContext());
5143094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
5153094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                ALOGE_IF(!success, "eglMakeCurrent -> internal failed");
5163094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian            }
5173094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
51899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        } break;
519edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
520edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
521edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
522edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer()
523edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
524841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
525b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian    // mSwapRegion can be empty here is some cases, for instance if a hidden
526b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian    // or fully transparent window is updating.
527b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian    // in that case, we need to flip anyways to not risk a deadlock with
528b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian    // h/w composer.
529b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian
5301b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    const DisplayHardware& hw(getDefaultDisplayHardware());
531a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    const nsecs_t now = systemTime();
532a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = now;
533a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    hw.flip(mSwapRegion);
534e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
535e8696a40e09b24b634214684d18526187b316a2fJamie Gennis    size_t numLayers = mVisibleLayersSortedByZ.size();
5361b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    HWComposer& hwc(hw.getHwComposer());
537ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall    if (hwc.initCheck() == NO_ERROR) {
538ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall        HWComposer::LayerListIterator cur = hwc.begin();
539ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall        const HWComposer::LayerListIterator end = hwc.end();
540ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall        for (size_t i = 0; cur != end && i < numLayers; ++i, ++cur) {
541ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall            mVisibleLayersSortedByZ[i]->onLayerDisplayed(&*cur);
542ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall        }
543ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall    } else {
544ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall        for (size_t i = 0; i < numLayers; i++) {
545ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall            mVisibleLayersSortedByZ[i]->onLayerDisplayed(NULL);
546ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall        }
547e8696a40e09b24b634214684d18526187b316a2fJamie Gennis    }
548e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
549a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mLastSwapBufferTime = systemTime() - now;
550a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = 0;
551a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mSwapRegion.clear();
552edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
553edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
554edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
555edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
556841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
557841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
558ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    Mutex::Autolock _l(mStateLock);
559ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    const nsecs_t now = systemTime();
560ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = now;
561ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
562ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // Here we're guaranteed that some transaction flags are set
563ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // so we can call handleTransactionLocked() unconditionally.
564ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // We call getTransactionFlags(), which will also clear the flags,
565ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // with mStateLock held to guarantee that mCurrentState won't change
566ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // until the transaction is committed.
567ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
568ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
569ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    transactionFlags = getTransactionFlags(mask);
570ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    handleTransactionLocked(transactionFlags);
571ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
572ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mLastTransactionTime = systemTime() - now;
573ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = 0;
574ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    invalidateHwcGeometry();
575ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // here the transaction has been committed
5763d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian}
577edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
578ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopianvoid SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
5793d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{
5803d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    const LayerVector& currentLayers(mCurrentState.layersSortedByZ);
581edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t count = currentLayers.size();
582edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
583edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
584edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Traversal of the children
585edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * (perform the transaction for each of them if needed)
586edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
587edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
588edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const bool layersNeedTransaction = transactionFlags & eTraversalNeeded;
589edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (layersNeedTransaction) {
590edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (size_t i=0 ; i<count ; i++) {
591076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            const sp<LayerBase>& layer = currentLayers[i];
592edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
593edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (!trFlags) continue;
594edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
595edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const uint32_t flags = layer->doTransaction(0);
596edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (flags & Layer::eVisibleRegion)
597edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mVisibleRegionsDirty = true;
598edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
599edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
600edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
601edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
602edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Perform our own transaction if needed
603edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
604edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
605edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (transactionFlags & eTransactionNeeded) {
606edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (mCurrentState.orientation != mDrawingState.orientation) {
607edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // the orientation has changed, recompute all visible regions
608edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // and invalidate everything.
609edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
6101b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian            const int dpy = 0; // TODO: should be a parameter
6111b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian            DisplayHardware& hw(const_cast<DisplayHardware&>(getDisplayHardware(dpy)));
612edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int orientation = mCurrentState.orientation;
6131b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian            hw.setOrientation(orientation);
614edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
615edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // update the shared control block
616edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            volatile display_cblk_t* dcblk = mServerCblk->displays + dpy;
617edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dcblk->orientation = orientation;
6181b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian            dcblk->w = hw.getUserWidth();
6191b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian            dcblk->h = hw.getUserHeight();
620edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
6211b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian            // FIXME: mVisibleRegionsDirty & mDirtyRegion should this be per DisplayHardware?
622edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
623edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mDirtyRegion.set(hw.bounds());
624edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
625edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
6260aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        if (currentLayers.size() > mDrawingState.layersSortedByZ.size()) {
6270aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            // layers have been added
628edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
629edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
630edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
6310aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        // some layers might have been removed, so
6320aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        // we need to update the regions they're exposing.
6330aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        if (mLayersRemoved) {
63448d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian            mLayersRemoved = false;
635edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
6360aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            const LayerVector& previousLayers(mDrawingState.layersSortedByZ);
6373d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian            const size_t count = previousLayers.size();
6383d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian            for (size_t i=0 ; i<count ; i++) {
6390aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                const sp<LayerBase>& layer(previousLayers[i]);
6400aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                if (currentLayers.indexOf( layer ) < 0) {
6410aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                    // this layer is not visible anymore
6425d7126b625c8c4a7b945e8c247b63abff7bc13b6Mathias Agopian                    mDirtyRegionRemovedLayer.orSelf(layer->visibleRegionScreen);
6430aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                }
6440aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            }
645edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
646edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
647edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
648edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    commitTransaction();
649edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
650edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
651edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::computeVisibleRegions(
6521bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian    const LayerVector& currentLayers, Region& dirtyRegion, Region& opaqueRegion)
653edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
654841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
655841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
6561b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    const DisplayHardware& hw(getDefaultDisplayHardware()); // FIXME: we shouldn't rely on DisplayHardware here
6571b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    const Transform& planeTransform(hw.getTransform());
658ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian    const Region screenRegion(hw.bounds());
659edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
660edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveOpaqueLayers;
661edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveCoveredLayers;
662edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region dirty;
663edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
664edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    bool secureFrameBuffer = false;
665edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
666edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t i = currentLayers.size();
667edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    while (i--) {
668076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        const sp<LayerBase>& layer = currentLayers[i];
6691b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian        layer->validateVisibility(planeTransform, hw);
670edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
671edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // start with the whole surface at its current location
672970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian        const Layer::State& s(layer->drawingState());
673edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
674ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
675ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * opaqueRegion: area of a surface that is fully opaque.
676ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
677edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region opaqueRegion;
678ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
679ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
680ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visibleRegion: area of a surface that is visible on screen
681ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * and not fully transparent. This is essentially the layer's
682ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * footprint minus the opaque regions above it.
683ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * Areas covered by a translucent surface are considered visible.
684ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
685edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region visibleRegion;
686ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
687ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
688ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * coveredRegion: area of a surface that is covered by all
689ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visible regions above it (which includes the translucent areas).
690ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
691edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region coveredRegion;
692ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
693ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
694ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // handle hidden surfaces by setting the visible region to empty
69599ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten        if (CC_LIKELY(!(s.flags & ISurfaceComposer::eLayerHidden) && s.alpha)) {
696a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            const bool translucent = !layer->isOpaque();
697970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian            const Rect bounds(layer->visibleBounds());
698edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            visibleRegion.set(bounds);
699ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            visibleRegion.andSelf(screenRegion);
700ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            if (!visibleRegion.isEmpty()) {
701ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // Remove the transparent area from the visible region
702ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (translucent) {
703ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    visibleRegion.subtractSelf(layer->transparentRegionScreen);
704ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
705edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
706ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // compute the opaque region
707ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                const int32_t layerOrientation = layer->getOrientation();
708ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (s.alpha==255 && !translucent &&
709ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                        ((layerOrientation & Transform::ROT_INVALID) == false)) {
710ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    // the opaque region is the layer's footprint
711ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    opaqueRegion = visibleRegion;
712ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
713edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
714edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
715edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
716ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Clip the covered region to the visible region
717ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        coveredRegion = aboveCoveredLayers.intersect(visibleRegion);
718ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
719ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveCoveredLayers for next (lower) layer
720ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        aboveCoveredLayers.orSelf(visibleRegion);
721ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
722edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // subtract the opaque region covered by the layers above us
723edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        visibleRegion.subtractSelf(aboveOpaqueLayers);
724edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
725edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // compute this layer's dirty region
726edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (layer->contentDirty) {
727edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // we need to invalidate the whole region
728edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dirty = visibleRegion;
729edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // as well, as the old visible region
730edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dirty.orSelf(layer->visibleRegionScreen);
731edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->contentDirty = false;
732edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
733a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian            /* compute the exposed region:
734ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   the exposed region consists of two components:
735ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   1) what's VISIBLE now and was COVERED before
736ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   2) what's EXPOSED now less what was EXPOSED before
737ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
738ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * note that (1) is conservative, we start with the whole
739ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * visible region but only keep what used to be covered by
740ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * something -- which mean it may have been exposed.
741ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
742ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * (2) handles areas that were not covered by anything but got
743ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * exposed because of a resize.
744a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian             */
745ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region newExposed = visibleRegion - coveredRegion;
746ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldVisibleRegion = layer->visibleRegionScreen;
747ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldCoveredRegion = layer->coveredRegionScreen;
748ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldExposed = oldVisibleRegion - oldCoveredRegion;
749ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed);
750edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
751edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirty.subtractSelf(aboveOpaqueLayers);
752edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
753edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // accumulate to the screen dirty region
754edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirtyRegion.orSelf(dirty);
755edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
756ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveOpaqueLayers for next (lower) layer
757edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        aboveOpaqueLayers.orSelf(opaqueRegion);
7588b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
759edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // Store the visible region is screen space
760edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setVisibleRegion(visibleRegion);
761edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setCoveredRegion(coveredRegion);
762edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
763970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian        // If a secure layer is partially visible, lock-down the screen!
764edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (layer->isSecure() && !visibleRegion.isEmpty()) {
765edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            secureFrameBuffer = true;
766edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
767edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
768edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
769970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian    // invalidate the areas where a layer was removed
770970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian    dirtyRegion.orSelf(mDirtyRegionRemovedLayer);
771970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian    mDirtyRegionRemovedLayer.clear();
772970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian
773edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mSecureFrameBuffer = secureFrameBuffer;
774edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    opaqueRegion = aboveOpaqueLayers;
775edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
776edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
777edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
778edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::commitTransaction()
779edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
7802f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall    if (!mLayersPendingRemoval.isEmpty()) {
7812f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall        // Notify removed layers now that they can't be drawn from
7822f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall        for (size_t i = 0; i < mLayersPendingRemoval.size(); i++) {
7832f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall            mLayersPendingRemoval[i]->onRemoved();
7842f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall        }
7852f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall        mLayersPendingRemoval.clear();
7862f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall    }
7872f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall
788edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDrawingState = mCurrentState;
78928378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    mTransationPending = false;
790cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mTransactionCV.broadcast();
791edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
792edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
793edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handlePageFlip()
794edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
7951c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
7961b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    const DisplayHardware& hw(getDefaultDisplayHardware()); // FIXME: it's a problem we need DisplayHardware here
79799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    const Region screenRegion(hw.bounds());
79899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
7991bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian    const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
80099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    const bool visibleRegions = lockPageFlip(currentLayers);
801edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
80299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        if (visibleRegions || mVisibleRegionsDirty) {
803edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            Region opaqueRegion;
804edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            computeVisibleRegions(currentLayers, mDirtyRegion, opaqueRegion);
8054da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
8064da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            /*
8074da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian             *  rebuild the visible layer list
8084da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian             */
8091bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian            const size_t count = currentLayers.size();
8104da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            mVisibleLayersSortedByZ.clear();
8114da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            mVisibleLayersSortedByZ.setCapacity(count);
8124da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            for (size_t i=0 ; i<count ; i++) {
8134da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian                if (!currentLayers[i]->visibleRegionScreen.isEmpty())
8144da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian                    mVisibleLayersSortedByZ.add(currentLayers[i]);
8154da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            }
8164da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
817edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mWormholeRegion = screenRegion.subtract(opaqueRegion);
818edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = false;
819ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian            invalidateHwcGeometry();
820edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
821edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
822edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    unlockPageFlip(currentLayers);
8230dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian
8240dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    mDirtyRegion.orSelf(getAndClearInvalidateRegion());
825edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDirtyRegion.andSelf(screenRegion);
826edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
827edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
828ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopianvoid SurfaceFlinger::invalidateHwcGeometry()
829ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian{
830ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian    mHwWorkListDirty = true;
831ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian}
832ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian
833edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool SurfaceFlinger::lockPageFlip(const LayerVector& currentLayers)
834edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
835edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    bool recomputeVisibleRegions = false;
836edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t count = currentLayers.size();
837076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBase> const* layers = currentLayers.array();
838edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (size_t i=0 ; i<count ; i++) {
839b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
840edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->lockPageFlip(recomputeVisibleRegions);
841edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
842edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return recomputeVisibleRegions;
843edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
844edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
845edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::unlockPageFlip(const LayerVector& currentLayers)
846edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
8471b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    const DisplayHardware& hw(getDefaultDisplayHardware()); // FIXME: it's a problem we need DisplayHardware here
8481b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    const Transform& planeTransform(hw.getTransform());
84999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    const size_t count = currentLayers.size();
850076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBase> const* layers = currentLayers.array();
851edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (size_t i=0 ; i<count ; i++) {
852b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
853edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->unlockPageFlip(planeTransform, mDirtyRegion);
854edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
855edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
856edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
85799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::handleRefresh()
85899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
85999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    bool needInvalidate = false;
86099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
86199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    const size_t count = currentLayers.size();
86299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
86399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
86499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        if (layer->onPreComposition()) {
86599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            needInvalidate = true;
86699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        }
86799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    }
86899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    if (needInvalidate) {
86999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        signalLayerUpdate();
87099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    }
87199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
87299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
87399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
8741b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopianvoid SurfaceFlinger::handleWorkList(const DisplayHardware& hw)
875a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian{
876a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    mHwWorkListDirty = false;
8771b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    HWComposer& hwc(hw.getHwComposer());
878a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    if (hwc.initCheck() == NO_ERROR) {
879a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        const Vector< sp<LayerBase> >& currentLayers(mVisibleLayersSortedByZ);
880a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        const size_t count = currentLayers.size();
881a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        hwc.createWorkList(count);
8823e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian
8833e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian        HWComposer::LayerListIterator cur = hwc.begin();
8843e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian        const HWComposer::LayerListIterator end = hwc.end();
8853e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian        for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
8863e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian            currentLayers[i]->setGeometry(*cur);
88753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian            if (mDebugDisableHWC || mDebugRegion) {
8883e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian                cur->setSkip(true);
88973d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian            }
890a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        }
891a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
892a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian}
893b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian
8941b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopianvoid SurfaceFlinger::handleRepaint(const DisplayHardware& hw)
895edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
896841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
897841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
898b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // compute the invalid region
8990656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian    mSwapRegion.orSelf(mDirtyRegion);
900edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
90199ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten    if (CC_UNLIKELY(mDebugRegion)) {
9021b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian        debugFlashRegions(hw);
903edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
904edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
905b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // set the frame buffer
906b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    glMatrixMode(GL_MODELVIEW);
907b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    glLoadIdentity();
908edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
909edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t flags = hw.getFlags();
910a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian    if (flags & DisplayHardware::SWAP_RECTANGLE) {
91129d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // we can redraw only what's dirty, but since SWAP_RECTANGLE only
91229d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // takes a rectangle, we must make sure to update that whole
91329d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // rectangle in that case
914a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        mDirtyRegion.set(mSwapRegion.bounds());
915edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
91695a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian        if (flags & DisplayHardware::PARTIAL_UPDATES) {
91729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // We need to redraw the rectangle that will be updated
918df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian            // (pushed to the framebuffer).
91995a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian            // This is needed because PARTIAL_UPDATES only takes one
92029d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // rectangle instead of a region (see DisplayHardware::flip())
9210656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian            mDirtyRegion.set(mSwapRegion.bounds());
922edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
92329d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // we need to redraw everything (the whole screen)
924edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mDirtyRegion.set(hw.bounds());
9250656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian            mSwapRegion = mDirtyRegion;
926edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
927edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
928edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
9291b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    setupHardwareComposer(hw);
9301b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    composeSurfaces(hw, mDirtyRegion);
931edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
9329c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    // update the swap region and clear the dirty region
9339c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    mSwapRegion.orSelf(mDirtyRegion);
934edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDirtyRegion.clear();
935edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
936edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
9371b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopianvoid SurfaceFlinger::setupHardwareComposer(const DisplayHardware& hw)
938edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
939f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    HWComposer& hwc(hw.getHwComposer());
9403e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    HWComposer::LayerListIterator cur = hwc.begin();
9413e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    const HWComposer::LayerListIterator end = hwc.end();
9423e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    if (cur == end) {
9439c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        return;
944edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
945a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
9464da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian    const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
94745721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    size_t count = layers.size();
948a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
949e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block    ALOGE_IF(hwc.getNumLayers() != count,
95045721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            "HAL number of layers (%d) doesn't match surfaceflinger (%d)",
95145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            hwc.getNumLayers(), count);
952a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
95345721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    // just to be extra-safe, use the smallest count
95424925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling    if (hwc.initCheck() == NO_ERROR) {
95524925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling        count = count < hwc.getNumLayers() ? count : hwc.getNumLayers();
95624925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling    }
957a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
95845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    /*
95945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     *  update the per-frame h/w composer data for each layer
96045721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     *  and build the transparent region of the FB
96145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     */
9623e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
963f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
9643e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian        layer->setPerFrameData(*cur);
965f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    }
966f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    status_t err = hwc.prepare();
967e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block    ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
968f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian}
969f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian
9701b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopianvoid SurfaceFlinger::composeSurfaces(const DisplayHardware& hw, const Region& dirty)
971f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian{
972cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian    HWComposer& hwc(hw.getHwComposer());
9733e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    HWComposer::LayerListIterator cur = hwc.begin();
9743e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    const HWComposer::LayerListIterator end = hwc.end();
975cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian
976cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian    const size_t fbLayerCount = hwc.getLayerCount(HWC_FRAMEBUFFER);
9773e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    if (cur==end || fbLayerCount) {
978a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        // Never touch the framebuffer if we don't have any framebuffer layers
97945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian
980b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian        if (hwc.getLayerCount(HWC_OVERLAY)) {
981b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // when using overlays, we assume a fully transparent framebuffer
982b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // NOTE: we could reduce how much we need to clear, for instance
983b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // remove where there are opaque FB layers. however, on some
984b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // GPUs doing a "clean slate" glClear might be more efficient.
985b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // We'll revisit later if needed.
986b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            glClearColor(0, 0, 0, 0);
987b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            glClear(GL_COLOR_BUFFER_BIT);
988b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian        } else {
989b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // screen is already cleared here
990b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            if (!mWormholeRegion.isEmpty()) {
991b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                // can happen with SurfaceView
992b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                drawWormhole();
993b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            }
994a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        }
9954b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian
996a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        /*
997a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian         * and then, render the layers targeted at the framebuffer
998a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian         */
9994b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian
1000a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
1001a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        const size_t count = layers.size();
10023e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian        for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
1003a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian            const sp<LayerBase>& layer(layers[i]);
1004a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian            const Region clip(dirty.intersect(layer->visibleRegionScreen));
1005a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian            if (!clip.isEmpty()) {
10063e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian                if (cur->getCompositionType() == HWC_OVERLAY) {
10073e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian                    if (i && (cur->getHints() & HWC_HINT_CLEAR_FB)
1008a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                            && layer->isOpaque()) {
1009b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                        // never clear the very first layer since we're
1010b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                        // guaranteed the FB is already cleared
10111b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian                        layer->clearWithOpenGL(hw, clip);
1012a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                    }
1013a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                    continue;
1014a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                }
1015a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                // render the layer
10161b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian                layer->draw(hw, clip);
10174b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian            }
10184b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian        }
10194b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian    }
1020edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1021edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
10221b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopianvoid SurfaceFlinger::debugFlashRegions(const DisplayHardware& hw)
1023edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
10240a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    const uint32_t flags = hw.getFlags();
102553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian    const int32_t height = hw.getHeight();
10260656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian    if (mSwapRegion.isEmpty()) {
102753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian        return;
102853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian    }
10290a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
1030a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian    if (!(flags & DisplayHardware::SWAP_RECTANGLE)) {
10310a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        const Region repaint((flags & DisplayHardware::PARTIAL_UPDATES) ?
10320a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian                mDirtyRegion.bounds() : hw.bounds());
10331b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian        composeSurfaces(hw, repaint);
10340a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    }
10350a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
1036c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_EXTERNAL_OES);
1037c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_2D);
1038edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_BLEND);
1039edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
10400926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    static int toggle = 0;
10410926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    toggle = 1 - toggle;
10420926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    if (toggle) {
10430a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        glColor4f(1, 0, 1, 1);
10440926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    } else {
10450a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        glColor4f(1, 1, 0, 1);
10460926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    }
1047edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
104820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    Region::const_iterator it = mDirtyRegion.begin();
104920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    Region::const_iterator const end = mDirtyRegion.end();
105020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    while (it != end) {
105120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        const Rect& r = *it++;
1052edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLfloat vertices[][2] = {
105353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.left,  height - r.top },
105453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.left,  height - r.bottom },
105553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.right, height - r.bottom },
105653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.right, height - r.top }
1057edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        };
1058edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glVertexPointer(2, GL_FLOAT, 0, vertices);
1059edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1060edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
10610a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
10620656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian    hw.flip(mSwapRegion);
1063edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1064edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mDebugRegion > 1)
10650a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        usleep(mDebugRegion * 1000);
1066edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1067edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1068edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::drawWormhole() const
1069edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1070edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Region region(mWormholeRegion.intersect(mDirtyRegion));
1071edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (region.isEmpty())
1072edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1073edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1074f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    glDisable(GL_TEXTURE_EXTERNAL_OES);
1075b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian    glDisable(GL_TEXTURE_2D);
1076f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    glDisable(GL_BLEND);
1077b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian    glColor4f(0,0,0,0);
1078f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian
1079f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    GLfloat vertices[4][2];
1080f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    glVertexPointer(2, GL_FLOAT, 0, vertices);
1081f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    Region::const_iterator it = region.begin();
1082f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    Region::const_iterator const end = region.end();
1083f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    while (it != end) {
1084f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        const Rect& r = *it++;
1085f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[0][0] = r.left;
1086f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[0][1] = r.top;
1087f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[1][0] = r.right;
1088f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[1][1] = r.top;
1089f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[2][0] = r.right;
1090f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[2][1] = r.bottom;
1091f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[3][0] = r.left;
1092f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[3][1] = r.bottom;
1093f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1094f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    }
1095edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1096edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1097076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::addLayer(const sp<LayerBase>& layer)
1098edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1099edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
1100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    addLayer_l(layer);
1101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
1102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1105076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::addLayer_l(const sp<LayerBase>& layer)
1106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1107f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian    ssize_t i = mCurrentState.layersSortedByZ.add(layer);
11081b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    return (i < 0) ? status_t(i) : status_t(NO_ERROR);
11091b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian}
11101b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
111196f0819f81293076e652792794a961543e6750d7Mathias Agopianssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
111296f0819f81293076e652792794a961543e6750d7Mathias Agopian        const sp<LayerBaseClient>& lbc)
11131b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
111496f0819f81293076e652792794a961543e6750d7Mathias Agopian    // attach this layer to the client
11154f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    size_t name = client->attachLayer(lbc);
11164f113740180b6512b43723c4728f262882dc9b45Mathias Agopian
11174f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    Mutex::Autolock _l(mStateLock);
111896f0819f81293076e652792794a961543e6750d7Mathias Agopian
111996f0819f81293076e652792794a961543e6750d7Mathias Agopian    // add this layer to the current state list
112096f0819f81293076e652792794a961543e6750d7Mathias Agopian    addLayer_l(lbc);
112196f0819f81293076e652792794a961543e6750d7Mathias Agopian
11224f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    return ssize_t(name);
112396f0819f81293076e652792794a961543e6750d7Mathias Agopian}
112496f0819f81293076e652792794a961543e6750d7Mathias Agopian
112596f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer)
112696f0819f81293076e652792794a961543e6750d7Mathias Agopian{
112796f0819f81293076e652792794a961543e6750d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
112896f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = purgatorizeLayer_l(layer);
112996f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR)
113096f0819f81293076e652792794a961543e6750d7Mathias Agopian        setTransactionFlags(eTransactionNeeded);
113196f0819f81293076e652792794a961543e6750d7Mathias Agopian    return err;
1132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1134076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase)
1135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1136b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<LayerBaseClient> lbc(layerBase->getLayerBaseClient());
1137b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (lbc != 0) {
11380d1561275e80073807ac04728951782d943f8882Mathias Agopian        mLayerMap.removeItem( lbc->getSurfaceBinder() );
1139b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    }
1140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase);
1141edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (index >= 0) {
1142076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved = true;
1143edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
1144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
11453d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    return status_t(index);
1146edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1147edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
11489a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase)
11499a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
115076cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    // First add the layer to the purgatory list, which makes sure it won't
115176cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    // go away, then remove it from the main list (through a transaction).
11529a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    ssize_t err = removeLayer_l(layerBase);
115376cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    if (err >= 0) {
115476cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian        mLayerPurgatory.add(layerBase);
115576cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    }
11568c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian
11572f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall    mLayersPendingRemoval.push(layerBase);
11580b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian
11593d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // it's possible that we don't find a layer, because it might
11603d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // have been destroyed already -- this is not technically an error
116196f0819f81293076e652792794a961543e6750d7Mathias Agopian    // from the user because there is a race between Client::destroySurface(),
116296f0819f81293076e652792794a961543e6750d7Mathias Agopian    // ~Client() and ~ISurface().
11639a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err;
11649a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
11659a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
116696f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::invalidateLayerVisibility(const sp<LayerBase>& layer)
1167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
116896f0819f81293076e652792794a961543e6750d7Mathias Agopian    layer->forceVisibilityTransaction();
116996f0819f81293076e652792794a961543e6750d7Mathias Agopian    setTransactionFlags(eTraversalNeeded);
117096f0819f81293076e652792794a961543e6750d7Mathias Agopian    return NO_ERROR;
1171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1173dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopianuint32_t SurfaceFlinger::peekTransactionFlags(uint32_t flags)
1174dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian{
1175dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian    return android_atomic_release_load(&mTransactionFlags);
1176dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian}
1177dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian
1178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags)
1179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return android_atomic_and(~flags, &mTransactionFlags) & flags;
1181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1183bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags)
1184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t old = android_atomic_or(flags, &mTransactionFlags);
1186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((old & flags)==0) { // wake the server up
118799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        signalTransaction();
1188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return old;
1190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1193b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennisvoid SurfaceFlinger::setTransactionState(const Vector<ComposerState>& state,
119428378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        int orientation, uint32_t flags) {
1195698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
1196cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
119728378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    uint32_t transactionFlags = 0;
1198b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis    if (mCurrentState.orientation != orientation) {
1199b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis        if (uint32_t(orientation)<=eOrientation270 || orientation==42) {
1200b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis            mCurrentState.orientation = orientation;
120128378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis            transactionFlags |= eTransactionNeeded;
1202b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis        } else if (orientation != eOrientationUnchanged) {
120332397c1cd3327905173b36baa6fd1c579bc328ffSteve Block            ALOGW("setTransactionState: ignoring unrecognized orientation: %d",
1204b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis                    orientation);
1205b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis        }
1206b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis    }
1207b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis
1208698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    const size_t count = state.size();
1209698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
1210698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const ComposerState& s(state[i]);
1211698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        sp<Client> client( static_cast<Client *>(s.client.get()) );
121228378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        transactionFlags |= setClientStateLocked(client, s.state);
1213698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    }
1214386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian
121528378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    if (transactionFlags) {
1216386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // this triggers the transaction
121728378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        setTransactionFlags(transactionFlags);
1218698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian
1219386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // if this is a synchronous transaction, wait for it to take effect
1220386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // before returning.
1221386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        if (flags & eSynchronous) {
1222386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            mTransationPending = true;
1223386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        }
1224386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        while (mTransationPending) {
1225386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
1226386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            if (CC_UNLIKELY(err != NO_ERROR)) {
1227386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                // just in case something goes wrong in SF, return to the
1228386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                // called after a few seconds.
122932397c1cd3327905173b36baa6fd1c579bc328ffSteve Block                ALOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!");
1230386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                mTransationPending = false;
1231386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                break;
1232386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            }
1233cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        }
1234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
12370ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopiansp<ISurface> SurfaceFlinger::createSurface(
12380ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        ISurfaceComposerClient::surface_data_t* params,
12390ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const String8& name,
12400ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const sp<Client>& client,
1241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        DisplayID d, uint32_t w, uint32_t h, PixelFormat format,
1242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t flags)
1243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1244076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBaseClient> layer;
1245a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    sp<ISurface> surfaceHandle;
12466e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian
12476e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    if (int32_t(w|h) < 0) {
1248e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE("createSurface() failed, w or h is negative (w=%d, h=%d)",
12496e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian                int(w), int(h));
12506e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian        return surfaceHandle;
12516e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    }
12528b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
1253ff615cc7a1cceedd705b0623b058c54669b29596Mathias Agopian    //ALOGD("createSurface for (%d x %d), name=%s", w, h, name.string());
1254b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<Layer> normalLayer;
1255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (flags & eFXSurfaceMask) {
1256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceNormal:
1257a5529c8778c2f407f482fc12165aeb76c0f505c2Mathias Agopian            normalLayer = createNormalSurface(client, d, w, h, flags, format);
1258a5529c8778c2f407f482fc12165aeb76c0f505c2Mathias Agopian            layer = normalLayer;
1259edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
1260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceBlur:
12611293a8eb567fd63c072a6970fa9dcf37d076059fMathias Agopian            // for now we treat Blur as Dim, until we can implement it
12621293a8eb567fd63c072a6970fa9dcf37d076059fMathias Agopian            // efficiently.
1263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceDim:
126496f0819f81293076e652792794a961543e6750d7Mathias Agopian            layer = createDimSurface(client, d, w, h, flags);
1265edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
1266118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        case eFXSurfaceScreenshot:
1267118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian            layer = createScreenshotSurface(client, d, w, h, flags);
1268118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian            break;
1269edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1271076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (layer != 0) {
127296f0819f81293076e652792794a961543e6750d7Mathias Agopian        layer->initStates(w, h, flags);
1273285dbde2e0cd0057be070ded3be8f5f453147edcMathias Agopian        layer->setName(name);
127496f0819f81293076e652792794a961543e6750d7Mathias Agopian        ssize_t token = addClientLayer(client, layer);
1275b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        surfaceHandle = layer->getSurface();
12778b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber        if (surfaceHandle != 0) {
127896f0819f81293076e652792794a961543e6750d7Mathias Agopian            params->token = token;
1279a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            params->identity = layer->getIdentity();
1280b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            if (normalLayer != 0) {
1281b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian                Mutex::Autolock _l(mStateLock);
1282a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                mLayerMap.add(layer->getSurfaceBinder(), normalLayer);
1283b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            }
12841c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        }
1285b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
128696f0819f81293076e652792794a961543e6750d7Mathias Agopian        setTransactionFlags(eTransactionNeeded);
1287edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1288edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1289edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return surfaceHandle;
1290edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1291edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1292b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<Layer> SurfaceFlinger::createNormalSurface(
1293f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        const sp<Client>& client, DisplayID display,
129496f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags,
12951c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        PixelFormat& format)
1296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize the surfaces
1298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (format) { // TODO: take h/w into account
1299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSPARENT:
1300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSLUCENT:
1301edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        format = PIXEL_FORMAT_RGBA_8888;
1302edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_OPAQUE:
1304a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888
1305a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian        format = PIXEL_FORMAT_RGB_565;
1306a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#else
13078f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian        format = PIXEL_FORMAT_RGBX_8888;
1308a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif
1309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1310edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1311edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1312a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888
1313a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian    if (format == PIXEL_FORMAT_RGBX_8888)
1314a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian        format = PIXEL_FORMAT_RGBA_8888;
1315a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif
1316a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian
131796f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<Layer> layer = new Layer(this, display, client);
1318f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian    status_t err = layer->setBuffers(w, h, format, flags);
131999ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten    if (CC_LIKELY(err != NO_ERROR)) {
1320e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE("createNormalSurfaceLocked() failed (%s)", strerror(-err));
1321076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        layer.clear();
1322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1323edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1324edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1325edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1326b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<LayerDim> SurfaceFlinger::createDimSurface(
1327f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        const sp<Client>& client, DisplayID display,
132896f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags)
1329edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
133096f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<LayerDim> layer = new LayerDim(this, display, client);
1331118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    return layer;
1332118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
1333118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
1334118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopiansp<LayerScreenshot> SurfaceFlinger::createScreenshotSurface(
1335118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        const sp<Client>& client, DisplayID display,
1336118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags)
1337118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{
1338118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    sp<LayerScreenshot> layer = new LayerScreenshot(this, display, client);
1339edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1340edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1341edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
134296f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeSurface(const sp<Client>& client, SurfaceID sid)
13439a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
13449a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    /*
13459a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     * called by the window manager, when a surface should be marked for
13469a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     * destruction.
13478b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber     *
13480aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * The surface is removed from the current and drawing lists, but placed
13490aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * in the purgatory queue, so it's not destroyed right-away (we need
13500aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * to wait for all client's references to go away first).
13519a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     */
13529a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
135348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    status_t err = NAME_NOT_FOUND;
13540aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian    Mutex::Autolock _l(mStateLock);
135596f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<LayerBaseClient> layer = client->getLayerUser(sid);
1356b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam
135748d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    if (layer != 0) {
135848d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        err = purgatorizeLayer_l(layer);
135948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        if (err == NO_ERROR) {
136048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian            setTransactionFlags(eTransactionNeeded);
136148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        }
13629a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    }
13639a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return err;
13649a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
13659a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
1366ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopianstatus_t SurfaceFlinger::destroySurface(const wp<LayerBaseClient>& layer)
1367edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1368759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian    // called by ~ISurface() when all references are gone
1369ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    status_t err = NO_ERROR;
1370ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    sp<LayerBaseClient> l(layer.promote());
1371ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    if (l != NULL) {
1372ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        Mutex::Autolock _l(mStateLock);
1373ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        err = removeLayer_l(l);
1374ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        if (err == NAME_NOT_FOUND) {
1375ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // The surface wasn't in the current list, which means it was
1376ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // removed already, which means it is in the purgatory,
1377ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // and need to be removed from there.
1378ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            ssize_t idx = mLayerPurgatory.remove(l);
1379e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block            ALOGE_IF(idx < 0,
1380ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian                    "layer=%p is not in the purgatory list", l.get());
1381f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        }
1382e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE_IF(err<0 && err != NAME_NOT_FOUND,
1383ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian                "error removing layer=%p (%s)", l.get(), strerror(-err));
1384ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    }
1385ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    return err;
1386edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1387edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1388698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopianuint32_t SurfaceFlinger::setClientStateLocked(
138996f0819f81293076e652792794a961543e6750d7Mathias Agopian        const sp<Client>& client,
1390698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const layer_state_t& s)
1391edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1392edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t flags = 0;
1393698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    sp<LayerBaseClient> layer(client->getLayerUser(s.surface));
1394698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    if (layer != 0) {
1395698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const uint32_t what = s.what;
1396698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & ePositionChanged) {
1397698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setPosition(s.x, s.y))
1398698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1399698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1400698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eLayerChanged) {
1401698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
1402698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setLayer(s.z)) {
1403698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                mCurrentState.layersSortedByZ.removeAt(idx);
1404698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                mCurrentState.layersSortedByZ.add(layer);
1405698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                // we need traversal (state changed)
1406698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                // AND transaction (list changed)
1407698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTransactionNeeded|eTraversalNeeded;
1408edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1409698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1410698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eSizeChanged) {
1411698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setSize(s.w, s.h)) {
1412698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1413edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1414edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1415698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eAlphaChanged) {
1416698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f)))
1417698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1418698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1419698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eMatrixChanged) {
1420698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setMatrix(s.matrix))
1421698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1422698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1423698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eTransparentRegionChanged) {
1424698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setTransparentRegionHint(s.transparentRegion))
1425698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1426698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1427698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eVisibilityChanged) {
1428698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setFlags(s.flags, s.mask))
1429698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1430698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1431f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        if (what & eCropChanged) {
1432f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis            if (layer->setCrop(s.crop))
1433f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis                flags |= eTraversalNeeded;
1434f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        }
1435edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1436698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    return flags;
1437edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1438edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1439b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// ---------------------------------------------------------------------------
1440b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
1441b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopianvoid SurfaceFlinger::onScreenAcquired() {
14428e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross    ALOGD("Screen about to return, flinger = %p", this);
14431b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    const DisplayHardware& hw(getDefaultDisplayHardware()); // XXX: this should be per DisplayHardware
1444b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    hw.acquireScreen();
144522ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian    mEventThread->onScreenAcquired();
1446b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    // this is a temporary work-around, eventually this should be called
1447b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    // by the power-manager
1448b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    SurfaceFlinger::turnElectronBeamOn(mElectronBeamAnimationMode);
144922ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian    // from this point on, SF will process updates again
14508acce2046ac7086c3dcfb1fc7c9c39f31de48694Mathias Agopian    repaintEverything();
1451edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1452edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1453b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopianvoid SurfaceFlinger::onScreenReleased() {
14548e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross    ALOGD("About to give-up screen, flinger = %p", this);
14551b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    const DisplayHardware& hw(getDefaultDisplayHardware()); // XXX: this should be per DisplayHardware
1456b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    if (hw.isScreenAcquired()) {
145722ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian        mEventThread->onScreenReleased();
1458b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        hw.releaseScreen();
1459b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        // from this point on, SF will stop drawing
1460b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    }
1461b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian}
1462b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
14638e533069e5721e55cb9768e140e16546c3a4a8b6Colin Crossvoid SurfaceFlinger::unblank() {
1464b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    class MessageScreenAcquired : public MessageBase {
1465b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        SurfaceFlinger* flinger;
1466b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    public:
1467b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        MessageScreenAcquired(SurfaceFlinger* flinger) : flinger(flinger) { }
1468b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        virtual bool handler() {
1469b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            flinger->onScreenAcquired();
1470b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            return true;
1471b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        }
1472b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    };
1473b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    sp<MessageBase> msg = new MessageScreenAcquired(this);
1474b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    postMessageSync(msg);
1475edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1476edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
14778e533069e5721e55cb9768e140e16546c3a4a8b6Colin Crossvoid SurfaceFlinger::blank() {
1478b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    class MessageScreenReleased : public MessageBase {
1479b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        SurfaceFlinger* flinger;
1480b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    public:
1481b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        MessageScreenReleased(SurfaceFlinger* flinger) : flinger(flinger) { }
1482b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        virtual bool handler() {
1483b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            flinger->onScreenReleased();
1484b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            return true;
1485b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        }
1486b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    };
1487b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    sp<MessageBase> msg = new MessageScreenReleased(this);
1488b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    postMessageSync(msg);
1489b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian}
1490b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
1491b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// ---------------------------------------------------------------------------
1492b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
1493edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
1494edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
14951d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling    const size_t SIZE = 4096;
1496edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char buffer[SIZE];
1497edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    String8 result;
149899b49840d309727678b77403d6cc9f920111623fMathias Agopian
149999b49840d309727678b77403d6cc9f920111623fMathias Agopian    if (!PermissionCache::checkCallingPermission(sDump)) {
1500edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        snprintf(buffer, SIZE, "Permission Denial: "
1501edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                "can't dump SurfaceFlinger from pid=%d, uid=%d\n",
1502edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                IPCThreadState::self()->getCallingPid(),
1503edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                IPCThreadState::self()->getCallingUid());
1504edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        result.append(buffer);
1505edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
15069795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // Try to get the main lock, but don't insist if we can't
15079795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // (this would indicate SF is stuck, but we want to be able to
15089795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // print something in dumpsys).
15099795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        int retry = 3;
15109795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        while (mStateLock.tryLock()<0 && --retry>=0) {
15119795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            usleep(1000000);
15129795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
15139795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const bool locked(retry >= 0);
15149795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (!locked) {
15158b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber            snprintf(buffer, SIZE,
15169795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "SurfaceFlinger appears to be unresponsive, "
15179795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "dumping anyways (no locks held)\n");
15189795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            result.append(buffer);
15199795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
15209795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
152182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        bool dumpAll = true;
152282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        size_t index = 0;
152325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        size_t numArgs = args.size();
152425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        if (numArgs) {
152525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
152625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--list"))) {
152725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                index++;
152825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                listLayersLocked(args, index, result, buffer, SIZE);
152935aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
153025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            }
153125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
153225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
153325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--latency"))) {
153482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                index++;
153582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                dumpStatsLocked(args, index, result, buffer, SIZE);
153635aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
153782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            }
153825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
153925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
154025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--latency-clear"))) {
154125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                index++;
154225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                clearStatsLocked(args, index, result, buffer, SIZE);
154335aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
154425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            }
1545edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
15461b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
154782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (dumpAll) {
154882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            dumpAllLocked(result, buffer, SIZE);
154982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
155048b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
155182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (locked) {
155282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mStateLock.unlock();
155348b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        }
155482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
155582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    write(fd, result.string(), result.size());
155682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    return NO_ERROR;
155782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
155848b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
155925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::listLayersLocked(const Vector<String16>& args, size_t& index,
156025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        String8& result, char* buffer, size_t SIZE) const
156125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
156225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
156325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const size_t count = currentLayers.size();
156425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
156525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
156625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        snprintf(buffer, SIZE, "%s\n", layer->getName().string());
156725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        result.append(buffer);
156825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
156925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
157025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
157182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index,
157282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        String8& result, char* buffer, size_t SIZE) const
157382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
157482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    String8 name;
157582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    if (index < args.size()) {
157682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        name = String8(args[index]);
157782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        index++;
157882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
157948b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
158082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
158182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const size_t count = currentLayers.size();
158282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    for (size_t i=0 ; i<count ; i++) {
158382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
158482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (name.isEmpty()) {
158582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            snprintf(buffer, SIZE, "%s\n", layer->getName().string());
158682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            result.append(buffer);
158782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
158882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (name.isEmpty() || (name == layer->getName())) {
158982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            layer->dumpStats(result, buffer, SIZE);
159082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
159182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
159282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
1593ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian
159425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& index,
159525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        String8& result, char* buffer, size_t SIZE) const
159625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
159725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    String8 name;
159825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    if (index < args.size()) {
159925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        name = String8(args[index]);
160025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        index++;
160125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
160225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
160325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
160425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const size_t count = currentLayers.size();
160525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
160625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
160725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        if (name.isEmpty() || (name == layer->getName())) {
160825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            layer->clearStats();
160925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        }
161025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
161125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
161225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
161382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpAllLocked(
161482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        String8& result, char* buffer, size_t SIZE) const
161582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
161682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    // figure out if we're stuck somewhere
161782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t now = systemTime();
161882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t inSwapBuffers(mDebugInSwapBuffers);
161982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t inTransaction(mDebugInTransaction);
162082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0;
162182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0;
1622bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
162382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
162482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump the visible layer list
162582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
162682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
162782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const size_t count = currentLayers.size();
162882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "Visible layers (count = %d)\n", count);
162982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
163082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    for (size_t i=0 ; i<count ; i++) {
163182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
163282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        layer->dump(result, buffer, SIZE);
163382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
1634bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
163582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
163682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump the layers in the purgatory
163782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
1638ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian
163982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const size_t purgatorySize = mLayerPurgatory.size();
164082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "Purgatory state (%d entries)\n", purgatorySize);
164182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
164282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    for (size_t i=0 ; i<purgatorySize ; i++) {
164382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
164482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        layer->shortDump(result, buffer, SIZE);
164582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
16461b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
164782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
164882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump SurfaceFlinger global state
164982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
16501b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
165182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "SurfaceFlinger global state:\n");
165282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
16531b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
16541b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    const DisplayHardware& hw(getDefaultDisplayHardware());
165582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const GLExtensions& extensions(GLExtensions::getInstance());
165682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "GLES: %s, %s, %s\n",
165782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            extensions.getVendor(),
165882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            extensions.getRenderer(),
165982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            extensions.getVersion());
166082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
1661d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
166282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "EGL : %s\n",
16631b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian            eglQueryString(hw.getEGLDisplay(),
166482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                    EGL_VERSION_HW_ANDROID));
166582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
166673d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian
166782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "EXTS: %s\n", extensions.getExtension());
166882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
16699795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
167082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    mWormholeRegion.dump(result, "WormholeRegion");
167182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE,
167282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  orientation=%d, canDraw=%d\n",
167382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mCurrentState.orientation, hw.canDraw());
167482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
167582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE,
167682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  last eglSwapBuffers() time: %f us\n"
167782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  last transaction time     : %f us\n"
1678c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian            "  transaction-flags         : %08x\n"
167982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  refresh-rate              : %f fps\n"
168082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  x-dpi                     : %f\n"
1681b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian            "  y-dpi                     : %f\n"
1682b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian            "  density                   : %f\n",
168382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mLastSwapBufferTime/1000.0,
168482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mLastTransactionTime/1000.0,
1685c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian            mTransactionFlags,
168682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            hw.getRefreshRate(),
168782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            hw.getDpiX(),
1688b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian            hw.getDpiY(),
1689b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian            hw.getDensity());
169082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
169182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
169282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "  eglSwapBuffers time: %f us\n",
169382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            inSwapBuffersDuration/1000.0);
169482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
169582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
169682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "  transaction time: %f us\n",
169782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            inTransactionDuration/1000.0);
169882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
169982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
170082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
170182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * VSYNC state
170282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
170382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    mEventThread->dump(result, buffer, SIZE);
170482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
170582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
170682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump HWComposer state
170782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
170882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    HWComposer& hwc(hw.getHwComposer());
170982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "h/w composer state:\n");
171082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
171182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "  h/w composer %s and %s\n",
171282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            hwc.initCheck()==NO_ERROR ? "present" : "not present",
171382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                    (mDebugDisableHWC || mDebugRegion) ? "disabled" : "enabled");
171482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
171582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    hwc.dump(result, buffer, SIZE, mVisibleLayersSortedByZ);
171682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
171782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
171882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump gralloc state
171982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
172082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
172182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    alloc.dump(result);
172282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    hw.dump(result);
1723edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1724edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1725edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::onTransact(
1726edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
1727edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1728edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (code) {
1729edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case CREATE_CONNECTION:
1730698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        case SET_TRANSACTION_STATE:
1731edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case SET_ORIENTATION:
1732edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case BOOT_FINISHED:
173359119e658a12279e8fff508f8773843de2d90917Mathias Agopian        case TURN_ELECTRON_BEAM_OFF:
17349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        case TURN_ELECTRON_BEAM_ON:
17358e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross        case BLANK:
17368e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross        case UNBLANK:
1737edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        {
1738edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // codes that require permission check
1739edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            IPCThreadState* ipc = IPCThreadState::self();
1740edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int pid = ipc->getCallingPid();
1741a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian            const int uid = ipc->getCallingUid();
174299b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
174399b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) {
1744e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block                ALOGE("Permission Denial: "
1745375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                        "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
1746375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                return PERMISSION_DENIED;
1747edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
17481b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
17491b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
17501b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        case CAPTURE_SCREEN:
17511b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
17521b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            // codes that require permission check
17531b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
17541b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int pid = ipc->getCallingPid();
17551b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int uid = ipc->getCallingUid();
175699b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
175799b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) {
1758e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block                ALOGE("Permission Denial: "
17591b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                        "can't read framebuffer pid=%d, uid=%d", pid, uid);
17601b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                return PERMISSION_DENIED;
17611b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            }
17621b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
1763edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1764edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
17651b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
1766edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
1767edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
1768b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        CHECK_INTERFACE(ISurfaceComposer, data, reply);
176999ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten        if (CC_UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) {
1770375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
1771375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int pid = ipc->getCallingPid();
1772375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int uid = ipc->getCallingUid();
1773e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block            ALOGE("Permission Denial: "
1774375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                    "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
1775edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return PERMISSION_DENIED;
1776edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1777edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int n;
1778edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        switch (code) {
177901b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian            case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE
178035b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian            case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE
1781edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1782edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1002:  // SHOW_UPDATES
1783edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                n = data.readInt32();
1784edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDebugRegion = n ? n : (mDebugRegion ? 0 : 1);
178553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
178653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
1787edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1788edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1004:{ // repaint everything
178953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
1790cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
1791cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            }
1792cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            case 1005:{ // force transaction
1793cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
1794cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
1795edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
17964d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            case 1006:{ // send empty update
17974d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian                signalRefresh();
17984d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian                return NO_ERROR;
17994d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            }
180053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian            case 1008:  // toggle use of hw composer
180153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                n = data.readInt32();
180253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                mDebugDisableHWC = n ? 1 : 0;
180353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
180453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
180553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                return NO_ERROR;
1806a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian            case 1009:  // toggle use of transform hint
1807a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                n = data.readInt32();
1808a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                mDebugDisableTransformHint = n ? 1 : 0;
1809a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                invalidateHwcGeometry();
1810a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                repaintEverything();
1811a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                return NO_ERROR;
1812edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1010:  // interrogate.
181301b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian                reply->writeInt32(0);
1814edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(0);
1815edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(mDebugRegion);
1816b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                reply->writeInt32(0);
181712839bee29bdcc65731b4d42029cc59e2320c5c4Dianne Hackborn                reply->writeInt32(mDebugDisableHWC);
1818edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1819edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1013: {
1820edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                Mutex::Autolock _l(mStateLock);
18211b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian                const DisplayHardware& hw(getDefaultDisplayHardware());
1822edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(hw.getPageFlipCount());
1823edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1824edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return NO_ERROR;
1825edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1826edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1827edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return err;
1828edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1829edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
183053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopianvoid SurfaceFlinger::repaintEverything() {
18311b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    const DisplayHardware& hw(getDefaultDisplayHardware()); // FIXME: this cannot be bound the default display
18320dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    const Rect bounds(hw.getBounds());
18330dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    setInvalidateRegion(Region(bounds));
183499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    signalTransaction();
183553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian}
183653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian
18370dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopianvoid SurfaceFlinger::setInvalidateRegion(const Region& reg) {
18380dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    Mutex::Autolock _l(mInvalidateLock);
18390dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    mInvalidateRegion = reg;
18400dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian}
18410dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian
18420dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias AgopianRegion SurfaceFlinger::getAndClearInvalidateRegion() {
18430dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    Mutex::Autolock _l(mInvalidateLock);
18440dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    Region reg(mInvalidateRegion);
18450dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    mInvalidateRegion.clear();
18460dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    return reg;
18470dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian}
18480dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian
184959119e658a12279e8fff508f8773843de2d90917Mathias Agopian// ---------------------------------------------------------------------------
185059119e658a12279e8fff508f8773843de2d90917Mathias Agopian
1851118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopianstatus_t SurfaceFlinger::renderScreenToTexture(DisplayID dpy,
1852118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        GLuint* textureName, GLfloat* uOut, GLfloat* vOut)
1853118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{
1854118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    Mutex::Autolock _l(mStateLock);
1855118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    return renderScreenToTextureLocked(dpy, textureName, uOut, vOut);
1856118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
1857118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
18589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::renderScreenToTextureLocked(DisplayID dpy,
18599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        GLuint* textureName, GLfloat* uOut, GLfloat* vOut)
186059119e658a12279e8fff508f8773843de2d90917Mathias Agopian{
186122ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian    ATRACE_CALL();
186222ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian
186359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
186459119e658a12279e8fff508f8773843de2d90917Mathias Agopian        return INVALID_OPERATION;
186559119e658a12279e8fff508f8773843de2d90917Mathias Agopian
186659119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // get screen geometry
18671b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    const DisplayHardware& hw(getDisplayHardware(dpy));
186859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    const uint32_t hw_w = hw.getWidth();
186959119e658a12279e8fff508f8773843de2d90917Mathias Agopian    const uint32_t hw_h = hw.getHeight();
187059119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLfloat u = 1;
187159119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLfloat v = 1;
187259119e658a12279e8fff508f8773843de2d90917Mathias Agopian
187359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // make sure to clear all GL error flags
187459119e658a12279e8fff508f8773843de2d90917Mathias Agopian    while ( glGetError() != GL_NO_ERROR ) ;
187559119e658a12279e8fff508f8773843de2d90917Mathias Agopian
187659119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // create a FBO
187759119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLuint name, tname;
187859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glGenTextures(1, &tname);
187959119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
1880a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1881a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
18829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
18839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            hw_w, hw_h, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
188459119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (glGetError() != GL_NO_ERROR) {
1885015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian        while ( glGetError() != GL_NO_ERROR ) ;
188659119e658a12279e8fff508f8773843de2d90917Mathias Agopian        GLint tw = (2 << (31 - clz(hw_w)));
188759119e658a12279e8fff508f8773843de2d90917Mathias Agopian        GLint th = (2 << (31 - clz(hw_h)));
18889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
18899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian                tw, th, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
189059119e658a12279e8fff508f8773843de2d90917Mathias Agopian        u = GLfloat(hw_w) / tw;
189159119e658a12279e8fff508f8773843de2d90917Mathias Agopian        v = GLfloat(hw_h) / th;
189259119e658a12279e8fff508f8773843de2d90917Mathias Agopian    }
189359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glGenFramebuffersOES(1, &name);
189459119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
18959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES,
18969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0);
189759119e658a12279e8fff508f8773843de2d90917Mathias Agopian
18989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // redraw the screen entirely...
1899c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_EXTERNAL_OES);
1900c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_2D);
19019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glClearColor(0,0,0,1);
19029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glClear(GL_COLOR_BUFFER_BIT);
1903a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glMatrixMode(GL_MODELVIEW);
1904a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glLoadIdentity();
19059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
19069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const size_t count = layers.size();
19079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (size_t i=0 ; i<count ; ++i) {
19089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
19091b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian        layer->drawForSreenShot(hw);
19109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
191159119e658a12279e8fff508f8773843de2d90917Mathias Agopian
1912118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    hw.compositionComplete();
1913118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
19149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // back to main framebuffer
19159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
19169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDeleteFramebuffersOES(1, &name);
191759119e658a12279e8fff508f8773843de2d90917Mathias Agopian
19189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *textureName = tname;
19199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *uOut = u;
19209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *vOut = v;
19219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
19229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
192359119e658a12279e8fff508f8773843de2d90917Mathias Agopian
19249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// ---------------------------------------------------------------------------
192559119e658a12279e8fff508f8773843de2d90917Mathias Agopian
1926ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopianclass VSyncWaiter {
1927ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    DisplayEventReceiver::Event buffer[4];
1928ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    sp<Looper> looper;
1929ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    sp<IDisplayEventConnection> events;
1930ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    sp<BitTube> eventTube;
1931ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopianpublic:
1932ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    VSyncWaiter(const sp<EventThread>& eventThread) {
1933ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        looper = new Looper(true);
1934ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        events = eventThread->createEventConnection();
1935ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        eventTube = events->getDataChannel();
1936ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        looper->addFd(eventTube->getFd(), 0, ALOOPER_EVENT_INPUT, 0, 0);
1937ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        events->requestNextVsync();
1938ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    }
1939ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
1940ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    void wait() {
1941ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        ssize_t n;
1942ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
1943ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        looper->pollOnce(-1);
1944ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        // we don't handle any errors here, it doesn't matter
1945ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        // and we don't want to take the risk to get stuck.
1946ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
1947ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        // drain the events...
1948ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        while ((n = DisplayEventReceiver::getEvents(
1949ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian                eventTube, buffer, 4)) > 0) ;
1950ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
1951ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        events->requestNextVsync();
1952ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    }
1953ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian};
1954ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
19559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::electronBeamOffAnimationImplLocked()
19569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
19579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // get screen geometry
19581b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    const DisplayHardware& hw(getDefaultDisplayHardware());
19599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_w = hw.getWidth();
19609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_h = hw.getHeight();
1961a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    const Region screenBounds(hw.getBounds());
196259119e658a12279e8fff508f8773843de2d90917Mathias Agopian
19639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat u, v;
19649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLuint tname;
1965118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    status_t result = renderScreenToTextureLocked(0, &tname, &u, &v);
19669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (result != NO_ERROR) {
19679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return result;
19689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
196959119e658a12279e8fff508f8773843de2d90917Mathias Agopian
19709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat vtx[8];
1971a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    const GLfloat texCoords[4][2] = { {0,0}, {0,v}, {u,v}, {u,0} };
19729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
19739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
19749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
19759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1976b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1977b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
19789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
19799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
19809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glVertexPointer(2, GL_FLOAT, 0, vtx);
19819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
1982ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    /*
1983ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     * Texture coordinate mapping
1984ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *
1985ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *                 u
1986ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *    1 +----------+---+
1987ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |     |    |   |  image is inverted
1988ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |     V    |   |  w.r.t. the texture
1989ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *  1-v +----------+   |  coordinates
1990ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |              |
1991ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |              |
1992ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |              |
1993ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *    0 +--------------+
1994ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      0              1
1995ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *
1996ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     */
1997ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian
19989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class s_curve_interpolator {
19999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float nbFrames, s, v;
20009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
20019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        s_curve_interpolator(int nbFrames, float s)
20029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : nbFrames(1.0f / (nbFrames-1)), s(s),
20039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian          v(1.0f + expf(-s + 0.5f*s)) {
20049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
20059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float operator()(int f) {
20069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const float x = f * nbFrames;
20079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f;
20089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
20099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
20109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class v_stretch {
20129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
20139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
20149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        v_stretch(uint32_t hw_w, uint32_t hw_h)
20159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
20169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
20179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
20189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w + (hw_w * v);
20199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = hw_h - (hw_h * v);
20209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
20219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
2022ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[0] = x;         vtx[1] = y;
2023ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
2024ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
2025ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
20269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
20279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
20289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class h_stretch {
20309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
20319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
20329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        h_stretch(uint32_t hw_w, uint32_t hw_h)
20339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
203459119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
20359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
20369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w - (hw_w * v);
20379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = 1.0f;
20389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
20399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
2040ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[0] = x;         vtx[1] = y;
2041ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
2042ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
2043ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
20449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
20459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
20469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2047ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    VSyncWaiter vsync(mEventThread);
2048ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
20499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // the full animation is 24 frames
2050ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    char value[PROPERTY_VALUE_MAX];
2051ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    property_get("debug.sf.electron_frames", value, "24");
2052ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    int nbFrames = (atoi(value) + 1) >> 1;
2053ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    if (nbFrames <= 0) // just in case
2054ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian        nbFrames = 24;
2055ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian
20569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itr(nbFrames, 7.5f);
20579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itg(nbFrames, 8.0f);
20589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itb(nbFrames, 8.5f);
20599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    v_stretch vverts(hw_w, hw_h);
2061a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian
2062a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glMatrixMode(GL_TEXTURE);
2063a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glLoadIdentity();
2064a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glMatrixMode(GL_MODELVIEW);
2065a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glLoadIdentity();
2066a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian
20679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnable(GL_BLEND);
20689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBlendFunc(GL_ONE, GL_ONE);
20699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=0 ; i<nbFrames ; i++) {
20709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float x, y, w, h;
20719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vr = itr(i);
20729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vg = itg(i);
20739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vb = itb(i);
20749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2075ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        // wait for vsync
2076ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        vsync.wait();
2077ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
20789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // clear screen
20799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(1,1,1,1);
20809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
20819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glEnable(GL_TEXTURE_2D);
208259119e658a12279e8fff508f8773843de2d90917Mathias Agopian
20839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the red plane
20849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vr);
20859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(1,0,0,1);
20869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
20879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the green plane
20899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vg);
20909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,1,0,1);
20919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
20929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the blue plane
20949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vb);
20959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,0,1,1);
20969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
20979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the white highlight (we use the last vertices)
209959119e658a12279e8fff508f8773843de2d90917Mathias Agopian        glDisable(GL_TEXTURE_2D);
210059119e658a12279e8fff508f8773843de2d90917Mathias Agopian        glColorMask(1,1,1,1);
21019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColor4f(vg, vg, vg, 1);
21029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
21039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
21049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
21059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    h_stretch hverts(hw_w, hw_h);
21079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_BLEND);
21089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_TEXTURE_2D);
21099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
21109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=0 ; i<nbFrames ; i++) {
21119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float v = itg(i);
21129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hverts(vtx, v);
2113ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
2114ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        // wait for vsync
2115ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        vsync.wait();
2116ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
21179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
21189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColor4f(1-v, 1-v, 1-v, 1);
21199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
21209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
21219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
21229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
21249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
21259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDeleteTextures(1, &tname);
2126a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    glDisable(GL_TEXTURE_2D);
2127c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_BLEND);
21289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
21299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
21309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::electronBeamOnAnimationImplLocked()
21329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
21339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    status_t result = PERMISSION_DENIED;
21349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
21369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return INVALID_OPERATION;
21379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // get screen geometry
21401b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    const DisplayHardware& hw(getDefaultDisplayHardware());
21419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_w = hw.getWidth();
21429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_h = hw.getHeight();
21439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const Region screenBounds(hw.bounds());
21449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat u, v;
21469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLuint tname;
21479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    result = renderScreenToTextureLocked(0, &tname, &u, &v);
21489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (result != NO_ERROR) {
21499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return result;
21509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
21519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat vtx[8];
21539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const GLfloat texCoords[4][2] = { {0,v}, {0,0}, {u,0}, {u,v} };
21549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
21559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
21569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
21579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2158b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2159b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
21609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
21619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
21629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glVertexPointer(2, GL_FLOAT, 0, vtx);
21639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class s_curve_interpolator {
21659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float nbFrames, s, v;
21669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
21679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        s_curve_interpolator(int nbFrames, float s)
21689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : nbFrames(1.0f / (nbFrames-1)), s(s),
21699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian          v(1.0f + expf(-s + 0.5f*s)) {
21709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
21719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float operator()(int f) {
21729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const float x = f * nbFrames;
21739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f;
21749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
21759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
21769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class v_stretch {
21789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
21799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
21809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        v_stretch(uint32_t hw_w, uint32_t hw_h)
21819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
218259119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
21839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
21849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w + (hw_w * v);
21859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = hw_h - (hw_h * v);
21869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
21879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
21889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[0] = x;         vtx[1] = y;
21899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
21909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
21919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
21929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
21939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
21949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class h_stretch {
21969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
21979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
21989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        h_stretch(uint32_t hw_w, uint32_t hw_h)
21999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
22009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
22019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
22029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w - (hw_w * v);
22039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = 1.0f;
22049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
22059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
22069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[0] = x;         vtx[1] = y;
22079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
22089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
22099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
22109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
22119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
22129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2213ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    VSyncWaiter vsync(mEventThread);
2214ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
2215a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian    // the full animation is 12 frames
2216a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian    int nbFrames = 8;
22179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itr(nbFrames, 7.5f);
22189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itg(nbFrames, 8.0f);
22199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itb(nbFrames, 8.5f);
22209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    h_stretch hverts(hw_w, hw_h);
22229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_BLEND);
22239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_TEXTURE_2D);
22249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
22259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=nbFrames-1 ; i>=0 ; i--) {
22269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float v = itg(i);
22279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hverts(vtx, v);
2228ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
2229ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        // wait for vsync
2230ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        vsync.wait();
2231ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
22329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
22339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColor4f(1-v, 1-v, 1-v, 1);
22349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
22359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
22369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
22379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2238a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian    nbFrames = 4;
22399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    v_stretch vverts(hw_w, hw_h);
22409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnable(GL_BLEND);
22419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBlendFunc(GL_ONE, GL_ONE);
22429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=nbFrames-1 ; i>=0 ; i--) {
22439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float x, y, w, h;
22449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vr = itr(i);
22459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vg = itg(i);
22469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vb = itb(i);
224759119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2248ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        // wait for vsync
2249ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        vsync.wait();
2250ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
22519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // clear screen
225259119e658a12279e8fff508f8773843de2d90917Mathias Agopian        glColorMask(1,1,1,1);
22539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
22549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glEnable(GL_TEXTURE_2D);
22559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the red plane
22579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vr);
22589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(1,0,0,1);
22599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
22609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the green plane
22629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vg);
22639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,1,0,1);
22649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
22659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the blue plane
22679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vb);
22689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,0,1,1);
22699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
22709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
227259119e658a12279e8fff508f8773843de2d90917Mathias Agopian    }
227359119e658a12279e8fff508f8773843de2d90917Mathias Agopian
22749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
22759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
227659119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glDeleteTextures(1, &tname);
2277a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    glDisable(GL_TEXTURE_2D);
2278c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_BLEND);
227959119e658a12279e8fff508f8773843de2d90917Mathias Agopian
22809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
22819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
22829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// ---------------------------------------------------------------------------
22849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2285abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOffImplLocked(int32_t mode)
22869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
228722ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian    ATRACE_CALL();
228822ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian
22891b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    DisplayHardware& hw(const_cast<DisplayHardware&>(getDefaultDisplayHardware()));
22909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (!hw.canDraw()) {
22919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // we're already off
22929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return NO_ERROR;
22939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
22947ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian
22957ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian    // turn off hwc while we're doing the animation
22967ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian    hw.getHwComposer().disable();
22977ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian    // and make sure to turn it back on (if needed) next time we compose
22987ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian    invalidateHwcGeometry();
22997ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian
2300abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    if (mode & ISurfaceComposer::eElectronBeamAnimationOff) {
2301abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        electronBeamOffAnimationImplLocked();
2302abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    }
2303abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian
2304abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    // always clear the whole screen at the end of the animation
2305abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    glClearColor(0,0,0,1);
2306abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    glClear(GL_COLOR_BUFFER_BIT);
2307abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    hw.flip( Region(hw.bounds()) );
2308abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian
2309015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian    return NO_ERROR;
231059119e658a12279e8fff508f8773843de2d90917Mathias Agopian}
231159119e658a12279e8fff508f8773843de2d90917Mathias Agopian
231259119e658a12279e8fff508f8773843de2d90917Mathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOff(int32_t mode)
231359119e658a12279e8fff508f8773843de2d90917Mathias Agopian{
231459119e658a12279e8fff508f8773843de2d90917Mathias Agopian    class MessageTurnElectronBeamOff : public MessageBase {
231559119e658a12279e8fff508f8773843de2d90917Mathias Agopian        SurfaceFlinger* flinger;
2316abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        int32_t mode;
231759119e658a12279e8fff508f8773843de2d90917Mathias Agopian        status_t result;
231859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    public:
2319abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        MessageTurnElectronBeamOff(SurfaceFlinger* flinger, int32_t mode)
2320abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            : flinger(flinger), mode(mode), result(PERMISSION_DENIED) {
232159119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
232259119e658a12279e8fff508f8773843de2d90917Mathias Agopian        status_t getResult() const {
232359119e658a12279e8fff508f8773843de2d90917Mathias Agopian            return result;
232459119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
232559119e658a12279e8fff508f8773843de2d90917Mathias Agopian        virtual bool handler() {
232659119e658a12279e8fff508f8773843de2d90917Mathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
2327abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            result = flinger->turnElectronBeamOffImplLocked(mode);
232859119e658a12279e8fff508f8773843de2d90917Mathias Agopian            return true;
232959119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
233059119e658a12279e8fff508f8773843de2d90917Mathias Agopian    };
233159119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2332abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    sp<MessageBase> msg = new MessageTurnElectronBeamOff(this, mode);
233359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    status_t res = postMessageSync(msg);
233459119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (res == NO_ERROR) {
233559119e658a12279e8fff508f8773843de2d90917Mathias Agopian        res = static_cast<MessageTurnElectronBeamOff*>( msg.get() )->getResult();
23369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
23379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // work-around: when the power-manager calls us we activate the
23389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // animation. eventually, the "on" animation will be called
23399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // by the power-manager itself
2340abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        mElectronBeamAnimationMode = mode;
234159119e658a12279e8fff508f8773843de2d90917Mathias Agopian    }
234259119e658a12279e8fff508f8773843de2d90917Mathias Agopian    return res;
234359119e658a12279e8fff508f8773843de2d90917Mathias Agopian}
234459119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2345edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
2346edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2347abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOnImplLocked(int32_t mode)
23489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
23491b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    DisplayHardware& hw(const_cast<DisplayHardware&>(getDefaultDisplayHardware()));
23509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (hw.canDraw()) {
23519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // we're already on
23529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return NO_ERROR;
23539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
2354abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    if (mode & ISurfaceComposer::eElectronBeamAnimationOn) {
2355abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        electronBeamOnAnimationImplLocked();
2356abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    }
2357a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian
2358a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian    // make sure to redraw the whole screen when the animation is done
2359a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian    mDirtyRegion.set(hw.bounds());
236099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    signalTransaction();
2361a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian
2362015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian    return NO_ERROR;
23639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
23649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
23659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOn(int32_t mode)
23669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
23679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class MessageTurnElectronBeamOn : public MessageBase {
23689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        SurfaceFlinger* flinger;
2369abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        int32_t mode;
23709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        status_t result;
23719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
2372abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        MessageTurnElectronBeamOn(SurfaceFlinger* flinger, int32_t mode)
2373abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            : flinger(flinger), mode(mode), result(PERMISSION_DENIED) {
23749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
23759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        status_t getResult() const {
23769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return result;
23779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
23789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        virtual bool handler() {
23799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
2380abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            result = flinger->turnElectronBeamOnImplLocked(mode);
23819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return true;
23829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
23839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
23849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2385abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    postMessageAsync( new MessageTurnElectronBeamOn(this, mode) );
23869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
23879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
23889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
23899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// ---------------------------------------------------------------------------
23909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
239174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopianstatus_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy,
239274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        sp<IMemoryHeap>* heap,
239374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t* w, uint32_t* h, PixelFormat* f,
2394bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t sw, uint32_t sh,
2395bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ, uint32_t maxLayerZ)
239674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{
2397fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian    ATRACE_CALL();
2398fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian
239974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    status_t result = PERMISSION_DENIED;
240074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
240174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // only one display supported for now
240299ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten    if (CC_UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
240374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return BAD_VALUE;
240474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
240574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
240674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return INVALID_OPERATION;
240774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
240874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // get screen geometry
24091b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    const DisplayHardware& hw(getDisplayHardware(dpy));
241074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const uint32_t hw_w = hw.getWidth();
241174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const uint32_t hw_h = hw.getHeight();
241274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
241374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    if ((sw > hw_w) || (sh > hw_h))
241474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return BAD_VALUE;
241574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
241674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    sw = (!sw) ? hw_w : sw;
241774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    sh = (!sh) ? hw_h : sh;
241874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const size_t size = sw * sh * 4;
241974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
24209d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block    //ALOGD("screenshot: sw=%d, sh=%d, minZ=%d, maxZ=%d",
24211c71a47a6db679a3212f0c99e14f330d6da500faMathias Agopian    //        sw, sh, minLayerZ, maxLayerZ);
2422c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
242374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // make sure to clear all GL error flags
242474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    while ( glGetError() != GL_NO_ERROR ) ;
242574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
242674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // create a FBO
242774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    GLuint name, tname;
242874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glGenRenderbuffersOES(1, &tname);
242974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindRenderbufferOES(GL_RENDERBUFFER_OES, tname);
243074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA8_OES, sw, sh);
2431fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian
243274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glGenFramebuffersOES(1, &name);
243374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
243474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES,
243574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, tname);
243674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
243774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
2438c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
243974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    if (status == GL_FRAMEBUFFER_COMPLETE_OES) {
244074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
244174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // invert everything, b/c glReadPixel() below will invert the FB
244274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glViewport(0, 0, sw, sh);
244374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_PROJECTION);
244474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glPushMatrix();
244574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glLoadIdentity();
2446ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian        glOrthof(0, hw_w, hw_h, 0, 0, 1);
244774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_MODELVIEW);
244874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
244974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // redraw the screen entirely...
245074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glClearColor(0,0,0,1);
245174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
2452f653b897a449e10d6cbfb6e0812f7b0bb02d6482Mathias Agopian
24539575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        const LayerVector& layers(mDrawingState.layersSortedByZ);
24549575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        const size_t count = layers.size();
245574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        for (size_t i=0 ; i<count ; ++i) {
245674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            const sp<LayerBase>& layer(layers[i]);
2457b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian            const uint32_t flags = layer->drawingState().flags;
2458b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian            if (!(flags & ISurfaceComposer::eLayerHidden)) {
2459b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                const uint32_t z = layer->drawingState().z;
2460b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                if (z >= minLayerZ && z <= maxLayerZ) {
24611b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian                    layer->drawForSreenShot(hw);
2462b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                }
2463bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian            }
246474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        }
246574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
246674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // check for errors and return screen capture
246774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        if (glGetError() != GL_NO_ERROR) {
246874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // error while rendering
246974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            result = INVALID_OPERATION;
247074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        } else {
247174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // allocate shared memory large enough to hold the
247274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // screen capture
247374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            sp<MemoryHeapBase> base(
247474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    new MemoryHeapBase(size, 0, "screen-capture") );
247574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            void* const ptr = base->getBase();
247674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            if (ptr) {
247774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                // capture the screen with glReadPixels()
2478fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian                ScopedTrace _t(ATRACE_TAG, "glReadPixels");
247974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                glReadPixels(0, 0, sw, sh, GL_RGBA, GL_UNSIGNED_BYTE, ptr);
248074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                if (glGetError() == GL_NO_ERROR) {
248174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *heap = base;
248274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *w = sw;
248374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *h = sh;
248474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *f = PIXEL_FORMAT_RGBA_8888;
248574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    result = NO_ERROR;
248674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                }
248774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            } else {
248874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                result = NO_MEMORY;
248974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            }
249074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        }
249174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glViewport(0, 0, hw_w, hw_h);
249274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_PROJECTION);
249374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glPopMatrix();
249474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_MODELVIEW);
249574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    } else {
249674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        result = BAD_VALUE;
249774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    }
249874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
249974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // release FBO resources
250074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
250174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glDeleteRenderbuffersOES(1, &tname);
250274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glDeleteFramebuffersOES(1, &name);
2503e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian
2504e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian    hw.compositionComplete();
2505e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian
25069d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block    // ALOGD("screenshot: result = %s", result<0 ? strerror(result) : "OK");
2507c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
250874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    return result;
250974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian}
251074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
251174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
25121b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopianstatus_t SurfaceFlinger::captureScreen(DisplayID dpy,
25131b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        sp<IMemoryHeap>* heap,
251474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t* width, uint32_t* height, PixelFormat* format,
2515bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t sw, uint32_t sh,
2516bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ, uint32_t maxLayerZ)
25171b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian{
25181b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    // only one display supported for now
251999ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten    if (CC_UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
25201b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        return BAD_VALUE;
25211b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
25221b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
25231b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        return INVALID_OPERATION;
25241b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
25251b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    class MessageCaptureScreen : public MessageBase {
25261b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        SurfaceFlinger* flinger;
25271b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        DisplayID dpy;
25281b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        sp<IMemoryHeap>* heap;
25291b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        uint32_t* w;
25301b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        uint32_t* h;
25311b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        PixelFormat* f;
253274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t sw;
253374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t sh;
2534bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ;
2535bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t maxLayerZ;
25361b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        status_t result;
25371b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    public:
25381b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        MessageCaptureScreen(SurfaceFlinger* flinger, DisplayID dpy,
253974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                sp<IMemoryHeap>* heap, uint32_t* w, uint32_t* h, PixelFormat* f,
2540bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                uint32_t sw, uint32_t sh,
2541bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                uint32_t minLayerZ, uint32_t maxLayerZ)
25421b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            : flinger(flinger), dpy(dpy),
2543bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              heap(heap), w(w), h(h), f(f), sw(sw), sh(sh),
2544bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              minLayerZ(minLayerZ), maxLayerZ(maxLayerZ),
2545bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              result(PERMISSION_DENIED)
25461b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
25471b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
25481b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        status_t getResult() const {
25491b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            return result;
25501b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
25511b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        virtual bool handler() {
25521b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
25531b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
25541b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            // if we have secure windows, never allow the screen capture
25551b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            if (flinger->mSecureFrameBuffer)
25561b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                return true;
25571b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
255874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            result = flinger->captureScreenImplLocked(dpy,
2559bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                    heap, w, h, f, sw, sh, minLayerZ, maxLayerZ);
25601b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
25611b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            return true;
25621b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
25631b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    };
25641b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
25651b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    sp<MessageBase> msg = new MessageCaptureScreen(this,
2566bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian            dpy, heap, width, height, format, sw, sh, minLayerZ, maxLayerZ);
25671b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    status_t res = postMessageSync(msg);
25681b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    if (res == NO_ERROR) {
25691b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        res = static_cast<MessageCaptureScreen*>( msg.get() )->getResult();
25701b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    }
25711b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    return res;
25721b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian}
25731b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
25741b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// ---------------------------------------------------------------------------
25751b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
2576b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<Layer> SurfaceFlinger::getLayer(const sp<ISurface>& sur) const
2577edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2578b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<Layer> result;
2579b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    Mutex::Autolock _l(mStateLock);
2580b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    result = mLayerMap.valueFor( sur->asBinder() ).promote();
2581b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return result;
2582b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
25837303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
2584b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// ---------------------------------------------------------------------------
258596f0819f81293076e652792794a961543e6750d7Mathias Agopian
25869a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::GraphicBufferAlloc() {}
25879a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
25889a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::~GraphicBufferAlloc() {}
25899a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
25909a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h,
2591d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        PixelFormat format, uint32_t usage, status_t* error) {
25929a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(w, h, format, usage));
25939a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    status_t err = graphicBuffer->initCheck();
2594d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian    *error = err;
2595a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (err != 0 || graphicBuffer->handle == 0) {
2596d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        if (err == NO_MEMORY) {
2597d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian            GraphicBuffer::dumpAllocationsToSystemLog();
2598d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        }
2599e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE("GraphicBufferAlloc::createGraphicBuffer(w=%d, h=%d) "
2600a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian             "failed (%s), handle=%p",
2601a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                w, h, strerror(-err), graphicBuffer->handle);
26029a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis        return 0;
26039a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    }
26049a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    return graphicBuffer;
26059a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis}
26069a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
26079a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis// ---------------------------------------------------------------------------
26089a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
2609edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
2610