SurfaceFlinger.cpp revision 6ee93c0d36dff1339eb2428be2d65441398e6e5f
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
62a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#include "DisplayHardware/FramebufferSurface.h"
63a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian#include "DisplayHardware/HWComposer.h"
64edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
651db13d79518f600d65a4fc006fe42900b890966eGlenn Kasten#include <private/android_filesystem_config.h>
6690ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include <private/gui/SharedBufferStack.h>
67ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian#include <gui/BitTube.h>
683094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian#include <gui/SurfaceTextureClient.h>
69a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
70bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian#define EGL_VERSION_HW_ANDROID  0x3143
71bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DISPLAY_COUNT       1
73edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
74edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
75edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
76edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
7799b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sHardwareTest("android.permission.HARDWARE_TEST");
7899b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER");
7999b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER");
8099b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sDump("android.permission.DUMP");
8199b49840d309727678b77403d6cc9f920111623fMathias Agopian
8299b49840d309727678b77403d6cc9f920111623fMathias Agopian// ---------------------------------------------------------------------------
8399b49840d309727678b77403d6cc9f920111623fMathias Agopian
84edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::SurfaceFlinger()
85edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    :   BnSurfaceComposer(), Thread(false),
86edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mTransactionFlags(0),
8728378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        mTransationPending(false),
88076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved(false),
89edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mBootTime(systemTime()),
90edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mVisibleRegionsDirty(false),
91a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        mHwWorkListDirty(false),
92abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        mElectronBeamAnimationMode(0),
93edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDebugRegion(0),
948afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian        mDebugDDMS(0),
9573d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian        mDebugDisableHWC(0),
96a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian        mDebugDisableTransformHint(0),
979795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInSwapBuffers(0),
989795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastSwapBufferTime(0),
999795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInTransaction(0),
1009795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastTransactionTime(0),
1013330b203039dea366d4981db1408a460134b2d2cMathias Agopian        mBootFinished(false),
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);
145a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
146a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
147a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglTerminate(display);
148edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
149edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
15099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::binderDied(const wp<IBinder>& who)
15199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
15299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // the window manager died on us. prepare its eulogy.
15399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
15499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // reset screen orientation
15599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    Vector<ComposerState> state;
15699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    setTransactionState(state, eOrientationDefault, 0);
15799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
15899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // restart the boot-animation
159a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    startBootAnim();
16099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
16199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
1627303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopiansp<IMemoryHeap> SurfaceFlinger::getCblk() const
163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1647303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    return mServerHeap;
165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1677e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopiansp<ISurfaceComposerClient> SurfaceFlinger::createConnection()
168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
16996f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<ISurfaceComposerClient> bclient;
17096f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<Client> client(new Client(this));
17196f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = client->initCheck();
17296f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR) {
17396f0819f81293076e652792794a961543e6750d7Mathias Agopian        bclient = client;
174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return bclient;
176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1789a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc()
1799a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis{
1809a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc());
1819a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    return gba;
1829a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis}
183b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::bootFinished()
185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t now = systemTime();
187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t duration = now - mBootTime;
188a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
1893330b203039dea366d4981db1408a460134b2d2cMathias Agopian    mBootFinished = true;
1901f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
1911f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // wait patiently for the window manager death
1921f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    const String16 name("window");
1931f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    sp<IBinder> window(defaultServiceManager()->getService(name));
1941f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    if (window != 0) {
1951f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian        window->linkToDeath(this);
1961f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    }
1971f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
1981f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // stop boot animation
199a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // formerly we would just kill the process, but we now ask it to exit so it
200a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // can choose where to stop the animation.
201a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("service.bootanim.exit", "1");
202edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
203edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
204a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianstatus_t SurfaceFlinger::selectConfigForPixelFormat(
205a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        EGLDisplay dpy,
206a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        EGLint const* attrs,
207a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        PixelFormat format,
208a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        EGLConfig* outConfig)
209a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian{
210a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLConfig config = NULL;
211a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLint numConfigs = -1, n=0;
212a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglGetConfigs(dpy, NULL, 0, &numConfigs);
213a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLConfig* const configs = new EGLConfig[numConfigs];
214a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglChooseConfig(dpy, attrs, configs, numConfigs, &n);
215a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    for (int i=0 ; i<n ; i++) {
216a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        EGLint nativeVisualId = 0;
217a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        eglGetConfigAttrib(dpy, configs[i], EGL_NATIVE_VISUAL_ID, &nativeVisualId);
218a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        if (nativeVisualId>0 && format == nativeVisualId) {
219a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            *outConfig = configs[i];
220a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            delete [] configs;
221a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            return NO_ERROR;
222a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        }
223a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    }
224a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    delete [] configs;
225a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    return NAME_NOT_FOUND;
226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
228a49126087b4494f4ef50873f3a3f6727265f6621Mathias AgopianEGLConfig SurfaceFlinger::selectEGLConfig(EGLDisplay display, EGLint nativeVisualId) {
229a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // select our EGLConfig. It must support EGL_RECORDABLE_ANDROID if
230a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // it is to be used with WIFI displays
231a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLConfig config;
232a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLint dummy;
233a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    status_t err;
234a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLint attribs[] = {
235a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            EGL_SURFACE_TYPE,           EGL_WINDOW_BIT,
236a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            EGL_RECORDABLE_ANDROID,     EGL_TRUE,
237a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            EGL_NONE
238a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    };
239a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    err = selectConfigForPixelFormat(display, attribs, nativeVisualId, &config);
240a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    if (err) {
241a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        // maybe we failed because of EGL_RECORDABLE_ANDROID
242a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        ALOGW("couldn't find an EGLConfig with EGL_RECORDABLE_ANDROID");
243a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        attribs[2] = EGL_NONE;
244a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        err = selectConfigForPixelFormat(display, attribs, nativeVisualId, &config);
245a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    }
246a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGE_IF(err, "couldn't find an EGLConfig matching the screen format");
247a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    if (eglGetConfigAttrib(display, config, EGL_CONFIG_CAVEAT, &dummy) == EGL_TRUE) {
248a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        ALOGW_IF(dummy == EGL_SLOW_CONFIG, "EGL_SLOW_CONFIG selected!");
249a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    }
250a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    return config;
251a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
253a49126087b4494f4ef50873f3a3f6727265f6621Mathias AgopianEGLContext SurfaceFlinger::createGLContext(EGLDisplay display, EGLConfig config) {
254a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // Also create our EGLContext
255a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLint contextAttributes[] = {
256a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#ifdef EGL_IMG_context_priority
257a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#ifdef HAS_CONTEXT_PRIORITY
258a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#warning "using EGL_IMG_context_priority"
259a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_HIGH_IMG,
260a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#endif
261a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#endif
262a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            EGL_NONE, EGL_NONE
263a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    };
264a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLContext ctxt = eglCreateContext(display, config, NULL, contextAttributes);
265a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGE_IF(ctxt==EGL_NO_CONTEXT, "EGLContext creation failed");
266a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    return ctxt;
267a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
269a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianvoid SurfaceFlinger::initializeGL(EGLDisplay display, EGLSurface surface) {
270a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLBoolean result = eglMakeCurrent(display, surface, surface, mEGLContext);
271a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    if (!result) {
272a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        ALOGE("Couldn't create a working GLES context. check logs. exiting...");
273a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        exit(0);
274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
276a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    GLExtensions& extensions(GLExtensions::getInstance());
277a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    extensions.initWithGLStrings(
278a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            glGetString(GL_VENDOR),
279a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            glGetString(GL_RENDERER),
280a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            glGetString(GL_VERSION),
281a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            glGetString(GL_EXTENSIONS),
282a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            eglQueryString(display, EGL_VENDOR),
283a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            eglQueryString(display, EGL_VERSION),
284a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            eglQueryString(display, EGL_EXTENSIONS));
2858b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
286a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLint w, h;
287a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglQuerySurface(display, surface, EGL_WIDTH,  &w);
288a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglQuerySurface(display, surface, EGL_HEIGHT, &h);
2898b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
290a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
291a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    glGetIntegerv(GL_MAX_VIEWPORT_DIMS, mMaxViewportDims);
2927303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
293edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
2948b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber    glPixelStorei(GL_PACK_ALIGNMENT, 4);
295edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glEnableClientState(GL_VERTEX_ARRAY);
296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glShadeModel(GL_FLAT);
297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_DITHER);
298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_CULL_FACE);
299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
300a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    struct pack565 {
301a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        inline uint16_t operator() (int r, int g, int b) const {
302a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            return (r<<11)|(g<<5)|b;
303a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        }
304a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    } pack565;
305a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint16_t g0 = pack565(0x0F,0x1F,0x0F);
307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint16_t g1 = pack565(0x17,0x2f,0x17);
3089575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    const uint16_t wormholeTexData[4] = { g0, g1, g1, g0 };
309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glGenTextures(1, &mWormholeTexName);
310edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glBindTexture(GL_TEXTURE_2D, mWormholeTexName);
311edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
312edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
313edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
314edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
315edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0,
3169575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis            GL_RGB, GL_UNSIGNED_SHORT_5_6_5, wormholeTexData);
3179575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis
3189575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    const uint16_t protTexData[] = { pack565(0x03, 0x03, 0x03) };
3199575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glGenTextures(1, &mProtectedTexName);
3209575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glBindTexture(GL_TEXTURE_2D, mProtectedTexName);
3219575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3229575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3239575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
3249575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
3259575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0,
3269575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis            GL_RGB, GL_UNSIGNED_SHORT_5_6_5, protTexData);
327edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
328edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glViewport(0, 0, w, h);
329edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glMatrixMode(GL_PROJECTION);
330edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glLoadIdentity();
331ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    // put the origin in the left-bottom corner
332ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    glOrthof(0, w, 0, h, 0, 1); // l=0, r=w ; b=0, t=h
333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
334a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // print some debugging info
335a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLint r,g,b,a;
336a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglGetConfigAttrib(display, mEGLConfig, EGL_RED_SIZE,   &r);
337a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglGetConfigAttrib(display, mEGLConfig, EGL_GREEN_SIZE, &g);
338a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglGetConfigAttrib(display, mEGLConfig, EGL_BLUE_SIZE,  &b);
339a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglGetConfigAttrib(display, mEGLConfig, EGL_ALPHA_SIZE, &a);
340a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("EGL informations:");
341a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("vendor    : %s", extensions.getEglVendor());
342a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("version   : %s", extensions.getEglVersion());
343a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("extensions: %s", extensions.getEglExtension());
344a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("Client API: %s", eglQueryString(display, EGL_CLIENT_APIS)?:"Not Supported");
345a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("EGLSurface: %d-%d-%d-%d, config=%p", r, g, b, a, mEGLConfig);
346a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("OpenGL ES informations:");
347a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("vendor    : %s", extensions.getVendor());
348a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("renderer  : %s", extensions.getRenderer());
349a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("version   : %s", extensions.getVersion());
350a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("extensions: %s", extensions.getExtension());
351a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("GL_MAX_TEXTURE_SIZE = %d", mMaxTextureSize);
352a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("GL_MAX_VIEWPORT_DIMS = %d x %d", mMaxViewportDims[0], mMaxViewportDims[1]);
353a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
354a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
355a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopiansurface_flinger_cblk_t* SurfaceFlinger::getControlBlock() const {
356a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    return mServerCblk;
357a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
358a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
359a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianstatus_t SurfaceFlinger::readyToRun()
360a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian{
361a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI(  "SurfaceFlinger's main thread ready to run. "
362a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            "Initializing graphics H/W...");
363a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
364a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // create the shared control-block
365a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    mServerHeap = new MemoryHeapBase(4096,
366a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            MemoryHeapBase::READ_ONLY, "SurfaceFlinger read-only heap");
367a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGE_IF(mServerHeap==0, "can't create shared memory dealer");
368a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    mServerCblk = static_cast<surface_flinger_cblk_t*>(mServerHeap->getBase());
369a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGE_IF(mServerCblk==0, "can't get to shared control block's address");
370a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    new(mServerCblk) surface_flinger_cblk_t;
371a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
372a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
373a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // initialize EGL
374a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
375a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglInitialize(display, NULL, NULL);
376a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
377a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // Initialize the main display
378a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // create native window to main display
379a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    sp<FramebufferSurface> anw = FramebufferSurface::create();
380a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ANativeWindow* const window = anw.get();
381a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    if (!window) {
382a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        ALOGE("Display subsystem failed to initialize. check logs. exiting...");
383a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        exit(0);
384a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    }
385a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
386a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // initialize the config and context
387a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    int format;
388a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    window->query(window, NATIVE_WINDOW_FORMAT, &format);
389a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    mEGLConfig  = selectEGLConfig(display, format);
390a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    mEGLContext = createGLContext(display, mEGLConfig);
391a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
392a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // initialize our main display hardware
393a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    DisplayHardware* const hw = new DisplayHardware(this, 0, anw, mEGLConfig);
394a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    mDisplayHardwares[0] = hw;
395a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
396a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    //  initialize OpenGL ES
397a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLSurface surface = hw->getEGLSurface();
398a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    initializeGL(display, surface);
399d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
400d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian    // start the EventThread
401d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian    mEventThread = new EventThread(this);
4028aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian    mEventQueue.setEventThread(mEventThread);
403edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
404a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // We're now ready to accept clients...
405d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian    mReadyToRunBarrier.open();
406d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
407a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    // start boot animation
408a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    startBootAnim();
4098b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
410edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
411edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
412edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
413a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopianvoid SurfaceFlinger::startBootAnim() {
414a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // start boot animation
415a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("service.bootanim.exit", "0");
416a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("ctl.start", "bootanim");
417a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian}
418a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian
419a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianuint32_t SurfaceFlinger::getMaxTextureSize() const {
420a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    return mMaxTextureSize;
421a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
422a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
423a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianuint32_t SurfaceFlinger::getMaxViewportDims() const {
424a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    return mMaxViewportDims[0] < mMaxViewportDims[1] ?
425a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            mMaxViewportDims[0] : mMaxViewportDims[1];
426a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
427a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
428edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
429d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
430582270d69db94286a248bd829f1ae6f910d45124Jamie Gennisbool SurfaceFlinger::authenticateSurfaceTexture(
431582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis        const sp<ISurfaceTexture>& surfaceTexture) const {
432134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    Mutex::Autolock _l(mStateLock);
433582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis    sp<IBinder> surfaceTextureBinder(surfaceTexture->asBinder());
434134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
435134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // Check the visible layer list for the ISurface
436134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
437134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    size_t count = currentLayers.size();
438134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    for (size_t i=0 ; i<count ; i++) {
439134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        const sp<LayerBase>& layer(currentLayers[i]);
440134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        sp<LayerBaseClient> lbc(layer->getLayerBaseClient());
441582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis        if (lbc != NULL) {
442582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder();
443582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            if (lbcBinder == surfaceTextureBinder) {
444582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis                return true;
445582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            }
446134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        }
447134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    }
448134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
449134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // Check the layers in the purgatory.  This check is here so that if a
450582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis    // SurfaceTexture gets destroyed before all the clients are done using it,
451582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis    // the error will not be reported as "surface XYZ is not authenticated", but
452134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // will instead fail later on when the client tries to use the surface,
453134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // which should be reported as "surface XYZ returned an -ENODEV".  The
454134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // purgatorized layers are no less authentic than the visible ones, so this
455134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // should not cause any harm.
456134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    size_t purgatorySize =  mLayerPurgatory.size();
457134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    for (size_t i=0 ; i<purgatorySize ; i++) {
458134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
459134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        sp<LayerBaseClient> lbc(layer->getLayerBaseClient());
460582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis        if (lbc != NULL) {
461582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder();
462582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            if (lbcBinder == surfaceTextureBinder) {
463582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis                return true;
464582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            }
465134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        }
466134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    }
467134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
468134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    return false;
469134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis}
470134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
471d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian// ----------------------------------------------------------------------------
472d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
473d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopiansp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection() {
4748aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian    return mEventThread->createEventConnection();
475bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian}
476bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
4773094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopianvoid SurfaceFlinger::connectDisplay(const sp<ISurfaceTexture> display) {
4781b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    const DisplayHardware& hw(getDefaultDisplayHardware());
4793094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    EGLSurface result = EGL_NO_SURFACE;
4803094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    EGLSurface old_surface = EGL_NO_SURFACE;
4813094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    sp<SurfaceTextureClient> stc;
4823094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
4833094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    if (display != NULL) {
4843094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        stc = new SurfaceTextureClient(display);
4853094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        result = eglCreateWindowSurface(hw.getEGLDisplay(),
486a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian                mEGLConfig, (EGLNativeWindowType)stc.get(), NULL);
4873094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        ALOGE_IF(result == EGL_NO_SURFACE,
4883094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                "eglCreateWindowSurface failed (ISurfaceTexture=%p)",
4893094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                display.get());
4903094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    }
4913094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
4923094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    { // scope for the lock
4933094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        Mutex::Autolock _l(mStateLock);
4943094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        old_surface = mExternalDisplaySurface;
4953094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        mExternalDisplayNativeWindow = stc;
4963094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        mExternalDisplaySurface = result;
4973094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        ALOGD("mExternalDisplaySurface = %p", result);
4983094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    }
4993094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
5003094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    if (old_surface != EGL_NO_SURFACE) {
5013094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        // Note: EGL allows to destroy an object while its current
5023094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        // it will fail to become current next time though.
5033094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        eglDestroySurface(hw.getEGLDisplay(), old_surface);
5043094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    }
5053094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian}
5063094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
5073094df359d1e6e2ae8ca4e935cc093f563804c96Mathias AgopianEGLSurface SurfaceFlinger::getExternalDisplaySurface() const {
5083094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    Mutex::Autolock _l(mStateLock);
5093094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    return mExternalDisplaySurface;
5103094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian}
5113094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
512edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
51399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
51499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::waitForEvent() {
51599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.waitMessage();
51699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
51799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
51899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalTransaction() {
51999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.invalidate();
52099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
52199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
52299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalLayerUpdate() {
52399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.invalidate();
52499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
52599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
52699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalRefresh() {
52799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.refresh();
52899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
52999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
53099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg,
53199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        nsecs_t reltime, uint32_t flags) {
53299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return mEventQueue.postMessage(msg, reltime);
53399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
53499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
53599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,
53699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        nsecs_t reltime, uint32_t flags) {
53799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    status_t res = mEventQueue.postMessage(msg, reltime);
53899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    if (res == NO_ERROR) {
53999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        msg->wait();
54099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    }
54199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return res;
54299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
543edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5444fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianbool SurfaceFlinger::threadLoop() {
545edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    waitForEvent();
54699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return true;
54799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
548edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5494fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::onMessageReceived(int32_t what) {
5501c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
55199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    switch (what) {
5524fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    case MessageQueue::INVALIDATE:
5534fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        handleMessageTransaction();
5544fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        handleMessageInvalidate();
5554fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        signalRefresh();
5564fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        break;
5574fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    case MessageQueue::REFRESH:
5584fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        handleMessageRefresh();
5594fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        break;
5604fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
5614fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5634fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageTransaction() {
5644fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
5654fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    uint32_t transactionFlags = peekTransactionFlags(mask);
5664fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    if (transactionFlags) {
5674fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        Region dirtyRegion;
5684fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        dirtyRegion = handleTransaction(transactionFlags);
5694fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // XXX: dirtyRegion should be per screen
5704fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        mDirtyRegion |= dirtyRegion;
5714fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
5724fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
573edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5744fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageInvalidate() {
5754fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    Region dirtyRegion;
5764fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    dirtyRegion = handlePageFlip();
5774fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    // XXX: dirtyRegion should be per screen
5784fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mDirtyRegion |= dirtyRegion;
5794fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
5803a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian
5814fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageRefresh() {
5824fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    handleRefresh();
583a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
5843b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    if (mVisibleRegionsDirty) {
5853b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        Region opaqueRegion;
5863b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        Region dirtyRegion;
5873b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
5883b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        computeVisibleRegions(currentLayers, dirtyRegion, opaqueRegion);
5893b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        mDirtyRegion.orSelf(dirtyRegion);
5903b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
5913b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        /*
5923b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian         *  rebuild the visible layer list per screen
5933b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian         */
5943b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
5953b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        // TODO: iterate through all displays
5963b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        DisplayHardware& hw(const_cast<DisplayHardware&>(getDisplayHardware(0)));
5973b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
5983b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        Vector< sp<LayerBase> > layersSortedByZ;
5993b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        const size_t count = currentLayers.size();
6003b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        for (size_t i=0 ; i<count ; i++) {
6013b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian            if (!currentLayers[i]->visibleRegion.isEmpty()) {
6023b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian                // TODO: also check that this layer is associated to this display
6033b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian                layersSortedByZ.add(currentLayers[i]);
6043b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian            }
6053b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        }
6063b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        hw.setVisibleLayersSortedByZ(layersSortedByZ);
6073b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
6083b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
6093b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        // FIXME: mWormholeRegion needs to be calculated per screen
6103b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        //const DisplayHardware& hw(getDefaultDisplayHardware()); // XXX: we can't keep that here
6113b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        mWormholeRegion = Region(hw.getBounds()).subtract(
6123b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian                hw.getTransform().transform(opaqueRegion) );
6133b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        mVisibleRegionsDirty = false;
6143b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        invalidateHwcGeometry();
6153b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
6163b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
6173b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
6184fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    // XXX: dirtyRegion should be per screen, we should check all of them
6194fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    if (mDirtyRegion.isEmpty()) {
6204fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        return;
6214fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
622303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian
6234fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    // TODO: iterate through all displays
6244fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    const DisplayHardware& hw(getDisplayHardware(0));
62569a655caef30663403802281210363f643ceb946Mathias Agopian
6264fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    // XXX: dirtyRegion should be per screen
6274fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    // transform the dirty region into this screen's coordinate space
6284fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    const Transform& planeTransform(hw.getTransform());
6294fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mDirtyRegion = planeTransform.transform(mDirtyRegion);
6304fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mDirtyRegion.orSelf(getAndClearInvalidateRegion());
6314fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mDirtyRegion.andSelf(hw.bounds());
632303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian
633b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian
6344fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    if (CC_UNLIKELY(mHwWorkListDirty)) {
6354fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // build the h/w work list
6364fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        handleWorkList(hw);
6374fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
6383094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
6394fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    if (CC_LIKELY(hw.canDraw())) {
6404fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // repaint the framebuffer (if needed)
6414fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        handleRepaint(hw);
6424fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // inform the h/w that we're done compositing
6434fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        hw.compositionComplete();
6444fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        postFramebuffer();
6454fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    } else {
6464fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // pretend we did the post
6474fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        hw.compositionComplete();
6484fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
6493094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
6504fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    // render to the external display if we have one
6514fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    EGLSurface externalDisplaySurface = getExternalDisplaySurface();
6524fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    if (externalDisplaySurface != EGL_NO_SURFACE) {
6534fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        EGLSurface cur = eglGetCurrentSurface(EGL_DRAW);
6544fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        EGLBoolean success = eglMakeCurrent(eglGetCurrentDisplay(),
6554fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                externalDisplaySurface, externalDisplaySurface,
6564fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                eglGetCurrentContext());
6574fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
6584fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        ALOGE_IF(!success, "eglMakeCurrent -> external failed");
6594fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
6604fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        if (success) {
6614fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            // redraw the screen entirely...
6624fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            glDisable(GL_TEXTURE_EXTERNAL_OES);
6634fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            glDisable(GL_TEXTURE_2D);
6644fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            glClearColor(0,0,0,1);
6654fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            glClear(GL_COLOR_BUFFER_BIT);
6664fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            glMatrixMode(GL_MODELVIEW);
6674fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            glLoadIdentity();
6683b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
6693b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian            const Vector< sp<LayerBase> >& layers( hw.getVisibleLayersSortedByZ() );
6704fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const size_t count = layers.size();
6714fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            for (size_t i=0 ; i<count ; ++i) {
6724fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                const sp<LayerBase>& layer(layers[i]);
6734fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                layer->drawForSreenShot(hw);
6744fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            }
6753094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
6764fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            success = eglSwapBuffers(eglGetCurrentDisplay(), externalDisplaySurface);
6774fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            ALOGE_IF(!success, "external display eglSwapBuffers failed");
6783094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
6794fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            hw.compositionComplete();
6804fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        }
6813094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
6824fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        success = eglMakeCurrent(eglGetCurrentDisplay(),
6834fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                cur, cur, eglGetCurrentContext());
6844fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
6854fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        ALOGE_IF(!success, "eglMakeCurrent -> internal failed");
686edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
6874fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
688edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
689edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
690edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer()
691edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
692841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
693b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian    // mSwapRegion can be empty here is some cases, for instance if a hidden
694b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian    // or fully transparent window is updating.
695b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian    // in that case, we need to flip anyways to not risk a deadlock with
696b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian    // h/w composer.
697b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian
6981b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    const DisplayHardware& hw(getDefaultDisplayHardware());
699c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall    HWComposer& hwc(hw.getHwComposer());
7003b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    const Vector< sp<LayerBase> >& layers(hw.getVisibleLayersSortedByZ());
7013b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    size_t numLayers = layers.size();
702a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    const nsecs_t now = systemTime();
703a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = now;
704c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall
705c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall    if (hwc.initCheck() == NO_ERROR) {
706c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall        HWComposer::LayerListIterator cur = hwc.begin();
707c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall        const HWComposer::LayerListIterator end = hwc.end();
708c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall        for (size_t i = 0; cur != end && i < numLayers; ++i, ++cur) {
709c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall            if (cur->getCompositionType() == HWC_OVERLAY) {
7103b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian                layers[i]->setAcquireFence(*cur);
711c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall            } else {
712c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall                cur->setAcquireFenceFd(-1);
713c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall            }
714c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall        }
715c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall    }
716c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall
717a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    hw.flip(mSwapRegion);
718e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
719ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall    if (hwc.initCheck() == NO_ERROR) {
720ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall        HWComposer::LayerListIterator cur = hwc.begin();
721ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall        const HWComposer::LayerListIterator end = hwc.end();
722ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall        for (size_t i = 0; cur != end && i < numLayers; ++i, ++cur) {
7233b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian            layers[i]->onLayerDisplayed(&*cur);
724ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall        }
725ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall    } else {
726ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall        for (size_t i = 0; i < numLayers; i++) {
7273b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian            layers[i]->onLayerDisplayed(NULL);
728ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall        }
729e8696a40e09b24b634214684d18526187b316a2fJamie Gennis    }
730e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
731a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mLastSwapBufferTime = systemTime() - now;
732a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = 0;
733a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mSwapRegion.clear();
734edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
735edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
7364fec873a98f7b4380720cd1ad006f74c8cdc73daMathias AgopianRegion SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
737edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
738841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
739841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
7404fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    Region dirtyRegion;
7414fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
742ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    Mutex::Autolock _l(mStateLock);
743ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    const nsecs_t now = systemTime();
744ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = now;
745ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
746ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // Here we're guaranteed that some transaction flags are set
747ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // so we can call handleTransactionLocked() unconditionally.
748ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // We call getTransactionFlags(), which will also clear the flags,
749ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // with mStateLock held to guarantee that mCurrentState won't change
750ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // until the transaction is committed.
751ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
752ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
753ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    transactionFlags = getTransactionFlags(mask);
7544fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    dirtyRegion = handleTransactionLocked(transactionFlags);
755ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
756ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mLastTransactionTime = systemTime() - now;
757ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = 0;
758ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    invalidateHwcGeometry();
759ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // here the transaction has been committed
7604fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
7614fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    return dirtyRegion;
7623d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian}
763edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
7644fec873a98f7b4380720cd1ad006f74c8cdc73daMathias AgopianRegion SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
7653d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{
7664fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    Region dirtyRegion;
7673d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    const LayerVector& currentLayers(mCurrentState.layersSortedByZ);
768edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t count = currentLayers.size();
769edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
770edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
771edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Traversal of the children
772edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * (perform the transaction for each of them if needed)
773edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
774edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
775edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const bool layersNeedTransaction = transactionFlags & eTraversalNeeded;
776edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (layersNeedTransaction) {
777edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (size_t i=0 ; i<count ; i++) {
778076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            const sp<LayerBase>& layer = currentLayers[i];
779edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
780edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (!trFlags) continue;
781edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
782edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const uint32_t flags = layer->doTransaction(0);
783edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (flags & Layer::eVisibleRegion)
784edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mVisibleRegionsDirty = true;
785edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
786edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
787edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
788edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
789edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Perform our own transaction if needed
790edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
791edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
792edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (transactionFlags & eTransactionNeeded) {
793edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (mCurrentState.orientation != mDrawingState.orientation) {
794edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // the orientation has changed, recompute all visible regions
795edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // and invalidate everything.
796edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
7971b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian            const int dpy = 0; // TODO: should be a parameter
7981b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian            DisplayHardware& hw(const_cast<DisplayHardware&>(getDisplayHardware(dpy)));
799edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int orientation = mCurrentState.orientation;
8001b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian            hw.setOrientation(orientation);
801edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
802edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // update the shared control block
803edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            volatile display_cblk_t* dcblk = mServerCblk->displays + dpy;
804edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dcblk->orientation = orientation;
8051b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian            dcblk->w = hw.getUserWidth();
8061b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian            dcblk->h = hw.getUserHeight();
807edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
8081b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian            // FIXME: mVisibleRegionsDirty & mDirtyRegion should this be per DisplayHardware?
809edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
810edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mDirtyRegion.set(hw.bounds());
811edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
812edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
8130aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        if (currentLayers.size() > mDrawingState.layersSortedByZ.size()) {
8140aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            // layers have been added
815edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
816edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
817edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
8180aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        // some layers might have been removed, so
8190aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        // we need to update the regions they're exposing.
8200aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        if (mLayersRemoved) {
82148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian            mLayersRemoved = false;
822edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
8230aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            const LayerVector& previousLayers(mDrawingState.layersSortedByZ);
8243d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian            const size_t count = previousLayers.size();
8253d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian            for (size_t i=0 ; i<count ; i++) {
8260aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                const sp<LayerBase>& layer(previousLayers[i]);
8270aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                if (currentLayers.indexOf( layer ) < 0) {
8280aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                    // this layer is not visible anymore
8294fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    // TODO: we could traverse the tree from front to back and compute the actual visible region
8304fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    // TODO: we could cache the transformed region
8314fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    Layer::State front(layer->drawingState());
8324fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    Region visibleReg = front.transform.transform(
8334fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            Region(Rect(front.active.w, front.active.h)));
8344fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    dirtyRegion.orSelf(visibleReg);
8350aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                }
8360aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            }
837edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
838edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
839edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
840edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    commitTransaction();
8414fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    return dirtyRegion;
8424fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
8434fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
8444fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::commitTransaction()
8454fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian{
8464fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    if (!mLayersPendingRemoval.isEmpty()) {
8474fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // Notify removed layers now that they can't be drawn from
8484fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        for (size_t i = 0; i < mLayersPendingRemoval.size(); i++) {
8494fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            mLayersPendingRemoval[i]->onRemoved();
8504fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        }
8514fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        mLayersPendingRemoval.clear();
8524fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
8534fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
8544fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mDrawingState = mCurrentState;
8554fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mTransationPending = false;
8564fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mTransactionCV.broadcast();
857edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
858edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
859edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::computeVisibleRegions(
8601bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian    const LayerVector& currentLayers, Region& dirtyRegion, Region& opaqueRegion)
861edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
862841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
863841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
864edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveOpaqueLayers;
865edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveCoveredLayers;
866edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region dirty;
867edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
8683b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    dirtyRegion.clear();
869edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
870edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t i = currentLayers.size();
871edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    while (i--) {
872076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        const sp<LayerBase>& layer = currentLayers[i];
873edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
874edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // start with the whole surface at its current location
875970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian        const Layer::State& s(layer->drawingState());
876edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
877ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
878ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * opaqueRegion: area of a surface that is fully opaque.
879ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
880edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region opaqueRegion;
881ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
882ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
883ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visibleRegion: area of a surface that is visible on screen
884ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * and not fully transparent. This is essentially the layer's
885ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * footprint minus the opaque regions above it.
886ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * Areas covered by a translucent surface are considered visible.
887ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
888edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region visibleRegion;
889ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
890ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
891ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * coveredRegion: area of a surface that is covered by all
892ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visible regions above it (which includes the translucent areas).
893ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
894edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region coveredRegion;
895ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
896ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
897ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // handle hidden surfaces by setting the visible region to empty
89899ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten        if (CC_LIKELY(!(s.flags & ISurfaceComposer::eLayerHidden) && s.alpha)) {
899a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            const bool translucent = !layer->isOpaque();
9004fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            Rect bounds(layer->computeBounds());
901edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            visibleRegion.set(bounds);
902ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            if (!visibleRegion.isEmpty()) {
903ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // Remove the transparent area from the visible region
904ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (translucent) {
9054fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    Region transparentRegionScreen;
9064fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    const Transform tr(s.transform);
9074fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    if (tr.transformed()) {
9084fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                        if (tr.preserveRects()) {
9094fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            // transform the transparent region
9104fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            transparentRegionScreen = tr.transform(s.transparentRegion);
9114fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                        } else {
9124fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            // transformation too complex, can't do the
9134fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            // transparent region optimization.
9144fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            transparentRegionScreen.clear();
9154fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                        }
9164fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    } else {
9174fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                        transparentRegionScreen = s.transparentRegion;
9184fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    }
9194fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    visibleRegion.subtractSelf(transparentRegionScreen);
920ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
921edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
922ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // compute the opaque region
9234fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                const int32_t layerOrientation = s.transform.getOrientation();
924ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (s.alpha==255 && !translucent &&
925ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                        ((layerOrientation & Transform::ROT_INVALID) == false)) {
926ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    // the opaque region is the layer's footprint
927ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    opaqueRegion = visibleRegion;
928ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
929edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
930edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
931edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
932ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Clip the covered region to the visible region
933ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        coveredRegion = aboveCoveredLayers.intersect(visibleRegion);
934ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
935ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveCoveredLayers for next (lower) layer
936ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        aboveCoveredLayers.orSelf(visibleRegion);
937ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
938edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // subtract the opaque region covered by the layers above us
939edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        visibleRegion.subtractSelf(aboveOpaqueLayers);
940edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
941edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // compute this layer's dirty region
942edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (layer->contentDirty) {
943edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // we need to invalidate the whole region
944edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dirty = visibleRegion;
945edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // as well, as the old visible region
9464fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            dirty.orSelf(layer->visibleRegion);
947edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->contentDirty = false;
948edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
949a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian            /* compute the exposed region:
950ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   the exposed region consists of two components:
951ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   1) what's VISIBLE now and was COVERED before
952ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   2) what's EXPOSED now less what was EXPOSED before
953ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
954ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * note that (1) is conservative, we start with the whole
955ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * visible region but only keep what used to be covered by
956ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * something -- which mean it may have been exposed.
957ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
958ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * (2) handles areas that were not covered by anything but got
959ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * exposed because of a resize.
960a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian             */
961ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region newExposed = visibleRegion - coveredRegion;
9624fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region oldVisibleRegion = layer->visibleRegion;
9634fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region oldCoveredRegion = layer->coveredRegion;
964ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldExposed = oldVisibleRegion - oldCoveredRegion;
965ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed);
966edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
967edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirty.subtractSelf(aboveOpaqueLayers);
968edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
969edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // accumulate to the screen dirty region
970edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirtyRegion.orSelf(dirty);
971edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
972ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveOpaqueLayers for next (lower) layer
973edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        aboveOpaqueLayers.orSelf(opaqueRegion);
9748b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
975edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // Store the visible region is screen space
976edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setVisibleRegion(visibleRegion);
977edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setCoveredRegion(coveredRegion);
978edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
979edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
980edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    opaqueRegion = aboveOpaqueLayers;
981edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
982edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
9834fec873a98f7b4380720cd1ad006f74c8cdc73daMathias AgopianRegion SurfaceFlinger::handlePageFlip()
984edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
9851c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
9864fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    Region dirtyRegion;
98799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
9881bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian    const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
989edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
9904fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    bool visibleRegions = false;
9914fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    const size_t count = currentLayers.size();
9924fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    sp<LayerBase> const* layers = currentLayers.array();
9934fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    for (size_t i=0 ; i<count ; i++) {
9944fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        const sp<LayerBase>& layer(layers[i]);
9954fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        dirtyRegion.orSelf( layer->latchBuffer(visibleRegions) );
9964fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
9974da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
9983b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    mVisibleRegionsDirty |= visibleRegions;
9990dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian
10004fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    return dirtyRegion;
1001edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1002edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1003ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopianvoid SurfaceFlinger::invalidateHwcGeometry()
1004ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian{
1005ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian    mHwWorkListDirty = true;
1006ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian}
1007ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian
100899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::handleRefresh()
100999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
101099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    bool needInvalidate = false;
101199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
101299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    const size_t count = currentLayers.size();
101399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
101499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
101599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        if (layer->onPreComposition()) {
101699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            needInvalidate = true;
101799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        }
101899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    }
101999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    if (needInvalidate) {
102099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        signalLayerUpdate();
102199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    }
102299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
102399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
102499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
10251b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopianvoid SurfaceFlinger::handleWorkList(const DisplayHardware& hw)
1026a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian{
1027a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    mHwWorkListDirty = false;
10281b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    HWComposer& hwc(hw.getHwComposer());
1029a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    if (hwc.initCheck() == NO_ERROR) {
10303b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        const Vector< sp<LayerBase> >& currentLayers(hw.getVisibleLayersSortedByZ());
1031a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        const size_t count = currentLayers.size();
1032a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        hwc.createWorkList(count);
10333e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian
10343e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian        HWComposer::LayerListIterator cur = hwc.begin();
10353e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian        const HWComposer::LayerListIterator end = hwc.end();
10363e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian        for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
10374fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            currentLayers[i]->setGeometry(hw, *cur);
103853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian            if (mDebugDisableHWC || mDebugRegion) {
10393e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian                cur->setSkip(true);
104073d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian            }
1041a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        }
1042a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
1043a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian}
1044b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian
10451b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopianvoid SurfaceFlinger::handleRepaint(const DisplayHardware& hw)
1046edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1047841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
1048841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
1049b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // compute the invalid region
10500656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian    mSwapRegion.orSelf(mDirtyRegion);
1051edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
105299ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten    if (CC_UNLIKELY(mDebugRegion)) {
10531b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian        debugFlashRegions(hw);
1054edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1055edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1056b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // set the frame buffer
1057b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    glMatrixMode(GL_MODELVIEW);
1058b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    glLoadIdentity();
1059edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1060edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t flags = hw.getFlags();
1061a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian    if (flags & DisplayHardware::SWAP_RECTANGLE) {
106229d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // we can redraw only what's dirty, but since SWAP_RECTANGLE only
106329d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // takes a rectangle, we must make sure to update that whole
106429d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // rectangle in that case
1065a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        mDirtyRegion.set(mSwapRegion.bounds());
1066edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
106795a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian        if (flags & DisplayHardware::PARTIAL_UPDATES) {
106829d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // We need to redraw the rectangle that will be updated
1069df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian            // (pushed to the framebuffer).
107095a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian            // This is needed because PARTIAL_UPDATES only takes one
107129d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // rectangle instead of a region (see DisplayHardware::flip())
10720656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian            mDirtyRegion.set(mSwapRegion.bounds());
1073edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
107429d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // we need to redraw everything (the whole screen)
1075edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mDirtyRegion.set(hw.bounds());
10760656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian            mSwapRegion = mDirtyRegion;
1077edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1078edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1079edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
10801b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    setupHardwareComposer(hw);
10811b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    composeSurfaces(hw, mDirtyRegion);
1082edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
10839c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    // update the swap region and clear the dirty region
10849c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    mSwapRegion.orSelf(mDirtyRegion);
1085edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDirtyRegion.clear();
1086edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1087edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
10881b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopianvoid SurfaceFlinger::setupHardwareComposer(const DisplayHardware& hw)
1089edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1090f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    HWComposer& hwc(hw.getHwComposer());
10913e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    HWComposer::LayerListIterator cur = hwc.begin();
10923e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    const HWComposer::LayerListIterator end = hwc.end();
10933e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    if (cur == end) {
10949c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        return;
1095edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1096a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
10973b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    const Vector< sp<LayerBase> >& layers(hw.getVisibleLayersSortedByZ());
109845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    size_t count = layers.size();
1099a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
1100e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block    ALOGE_IF(hwc.getNumLayers() != count,
110145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            "HAL number of layers (%d) doesn't match surfaceflinger (%d)",
110245721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            hwc.getNumLayers(), count);
1103a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
110445721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    // just to be extra-safe, use the smallest count
110524925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling    if (hwc.initCheck() == NO_ERROR) {
110624925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling        count = count < hwc.getNumLayers() ? count : hwc.getNumLayers();
110724925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling    }
1108a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
110945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    /*
111045721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     *  update the per-frame h/w composer data for each layer
111145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     *  and build the transparent region of the FB
111245721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     */
11133e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
1114f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
11153e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian        layer->setPerFrameData(*cur);
1116f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    }
1117f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    status_t err = hwc.prepare();
1118e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block    ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
1119f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian}
1120f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian
11211b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopianvoid SurfaceFlinger::composeSurfaces(const DisplayHardware& hw, const Region& dirty)
1122f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian{
1123cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian    HWComposer& hwc(hw.getHwComposer());
11243e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    HWComposer::LayerListIterator cur = hwc.begin();
11253e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    const HWComposer::LayerListIterator end = hwc.end();
1126cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian
1127cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian    const size_t fbLayerCount = hwc.getLayerCount(HWC_FRAMEBUFFER);
11283e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    if (cur==end || fbLayerCount) {
1129a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        // Never touch the framebuffer if we don't have any framebuffer layers
113045721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian
1131b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian        if (hwc.getLayerCount(HWC_OVERLAY)) {
1132b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // when using overlays, we assume a fully transparent framebuffer
1133b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // NOTE: we could reduce how much we need to clear, for instance
1134b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // remove where there are opaque FB layers. however, on some
1135b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // GPUs doing a "clean slate" glClear might be more efficient.
1136b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // We'll revisit later if needed.
1137b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            glClearColor(0, 0, 0, 0);
1138b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            glClear(GL_COLOR_BUFFER_BIT);
1139b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian        } else {
1140b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // screen is already cleared here
1141b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            if (!mWormholeRegion.isEmpty()) {
1142b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                // can happen with SurfaceView
1143b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                drawWormhole();
1144b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            }
1145a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        }
11464b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian
1147a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        /*
1148a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian         * and then, render the layers targeted at the framebuffer
1149a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian         */
11504b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian
11513b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        const Vector< sp<LayerBase> >& layers(hw.getVisibleLayersSortedByZ());
1152a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        const size_t count = layers.size();
11534fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        const Transform& tr = hw.getTransform();
1154a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall        for (size_t i=0 ; i<count ; ++i) {
1155a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian            const sp<LayerBase>& layer(layers[i]);
11564fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region clip(dirty.intersect(tr.transform(layer->visibleRegion)));
1157a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian            if (!clip.isEmpty()) {
1158a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall                if (cur != end && cur->getCompositionType() == HWC_OVERLAY) {
11593e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian                    if (i && (cur->getHints() & HWC_HINT_CLEAR_FB)
1160a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                            && layer->isOpaque()) {
1161b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                        // never clear the very first layer since we're
1162b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                        // guaranteed the FB is already cleared
11631b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian                        layer->clearWithOpenGL(hw, clip);
1164a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                    }
11656ee93c0d36dff1339eb2428be2d65441398e6e5fJesse Hall                    ++cur;
1166a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                    continue;
1167a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                }
1168a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                // render the layer
11691b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian                layer->draw(hw, clip);
11704b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian            }
1171a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall            if (cur != end) {
1172a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall                ++cur;
1173a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall            }
11744b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian        }
11754b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian    }
1176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
11781b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopianvoid SurfaceFlinger::debugFlashRegions(const DisplayHardware& hw)
1179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
11800a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    const uint32_t flags = hw.getFlags();
118153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian    const int32_t height = hw.getHeight();
11820656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian    if (mSwapRegion.isEmpty()) {
118353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian        return;
118453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian    }
11850a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
1186a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian    if (!(flags & DisplayHardware::SWAP_RECTANGLE)) {
11870a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        const Region repaint((flags & DisplayHardware::PARTIAL_UPDATES) ?
11880a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian                mDirtyRegion.bounds() : hw.bounds());
11891b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian        composeSurfaces(hw, repaint);
11900a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    }
11910a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
1192c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_EXTERNAL_OES);
1193c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_2D);
1194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_BLEND);
1195edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
11960926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    static int toggle = 0;
11970926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    toggle = 1 - toggle;
11980926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    if (toggle) {
11990a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        glColor4f(1, 0, 1, 1);
12000926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    } else {
12010a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        glColor4f(1, 1, 0, 1);
12020926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    }
1203edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
120420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    Region::const_iterator it = mDirtyRegion.begin();
120520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    Region::const_iterator const end = mDirtyRegion.end();
120620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    while (it != end) {
120720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        const Rect& r = *it++;
1208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLfloat vertices[][2] = {
120953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.left,  height - r.top },
121053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.left,  height - r.bottom },
121153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.right, height - r.bottom },
121253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.right, height - r.top }
1213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        };
1214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glVertexPointer(2, GL_FLOAT, 0, vertices);
1215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
12170a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
12180656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian    hw.flip(mSwapRegion);
1219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mDebugRegion > 1)
12210a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        usleep(mDebugRegion * 1000);
1222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::drawWormhole() const
1225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Region region(mWormholeRegion.intersect(mDirtyRegion));
1227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (region.isEmpty())
1228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1230f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    glDisable(GL_TEXTURE_EXTERNAL_OES);
1231b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian    glDisable(GL_TEXTURE_2D);
1232f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    glDisable(GL_BLEND);
1233b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian    glColor4f(0,0,0,0);
1234f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian
1235f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    GLfloat vertices[4][2];
1236f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    glVertexPointer(2, GL_FLOAT, 0, vertices);
1237f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    Region::const_iterator it = region.begin();
1238f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    Region::const_iterator const end = region.end();
1239f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    while (it != end) {
1240f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        const Rect& r = *it++;
1241f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[0][0] = r.left;
1242f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[0][1] = r.top;
1243f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[1][0] = r.right;
1244f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[1][1] = r.top;
1245f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[2][0] = r.right;
1246f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[2][1] = r.bottom;
1247f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[3][0] = r.left;
1248f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[3][1] = r.bottom;
1249f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1250f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    }
1251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1253076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::addLayer(const sp<LayerBase>& layer)
1254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
1256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    addLayer_l(layer);
1257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
1258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1259edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1261076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::addLayer_l(const sp<LayerBase>& layer)
1262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1263f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian    ssize_t i = mCurrentState.layersSortedByZ.add(layer);
12641b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    return (i < 0) ? status_t(i) : status_t(NO_ERROR);
12651b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian}
12661b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
126796f0819f81293076e652792794a961543e6750d7Mathias Agopianssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
126896f0819f81293076e652792794a961543e6750d7Mathias Agopian        const sp<LayerBaseClient>& lbc)
12691b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
127096f0819f81293076e652792794a961543e6750d7Mathias Agopian    // attach this layer to the client
12714f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    size_t name = client->attachLayer(lbc);
12724f113740180b6512b43723c4728f262882dc9b45Mathias Agopian
12734f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    Mutex::Autolock _l(mStateLock);
127496f0819f81293076e652792794a961543e6750d7Mathias Agopian
127596f0819f81293076e652792794a961543e6750d7Mathias Agopian    // add this layer to the current state list
127696f0819f81293076e652792794a961543e6750d7Mathias Agopian    addLayer_l(lbc);
127796f0819f81293076e652792794a961543e6750d7Mathias Agopian
12784f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    return ssize_t(name);
127996f0819f81293076e652792794a961543e6750d7Mathias Agopian}
128096f0819f81293076e652792794a961543e6750d7Mathias Agopian
128196f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer)
128296f0819f81293076e652792794a961543e6750d7Mathias Agopian{
128396f0819f81293076e652792794a961543e6750d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
128496f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = purgatorizeLayer_l(layer);
128596f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR)
128696f0819f81293076e652792794a961543e6750d7Mathias Agopian        setTransactionFlags(eTransactionNeeded);
128796f0819f81293076e652792794a961543e6750d7Mathias Agopian    return err;
1288edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1289edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1290076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase)
1291edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1292b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<LayerBaseClient> lbc(layerBase->getLayerBaseClient());
1293b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (lbc != 0) {
12940d1561275e80073807ac04728951782d943f8882Mathias Agopian        mLayerMap.removeItem( lbc->getSurfaceBinder() );
1295b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    }
1296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase);
1297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (index >= 0) {
1298076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved = true;
1299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
1300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
13013d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    return status_t(index);
1302edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
13049a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase)
13059a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
130676cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    // First add the layer to the purgatory list, which makes sure it won't
130776cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    // go away, then remove it from the main list (through a transaction).
13089a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    ssize_t err = removeLayer_l(layerBase);
130976cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    if (err >= 0) {
131076cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian        mLayerPurgatory.add(layerBase);
131176cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    }
13128c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian
13132f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall    mLayersPendingRemoval.push(layerBase);
13140b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian
13153d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // it's possible that we don't find a layer, because it might
13163d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // have been destroyed already -- this is not technically an error
131796f0819f81293076e652792794a961543e6750d7Mathias Agopian    // from the user because there is a race between Client::destroySurface(),
131896f0819f81293076e652792794a961543e6750d7Mathias Agopian    // ~Client() and ~ISurface().
13199a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err;
13209a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
13219a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
132296f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::invalidateLayerVisibility(const sp<LayerBase>& layer)
1323edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
132496f0819f81293076e652792794a961543e6750d7Mathias Agopian    layer->forceVisibilityTransaction();
132596f0819f81293076e652792794a961543e6750d7Mathias Agopian    setTransactionFlags(eTraversalNeeded);
132696f0819f81293076e652792794a961543e6750d7Mathias Agopian    return NO_ERROR;
1327edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1328edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1329dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopianuint32_t SurfaceFlinger::peekTransactionFlags(uint32_t flags)
1330dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian{
1331dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian    return android_atomic_release_load(&mTransactionFlags);
1332dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian}
1333dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian
1334edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags)
1335edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1336edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return android_atomic_and(~flags, &mTransactionFlags) & flags;
1337edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1338edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1339bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags)
1340edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1341edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t old = android_atomic_or(flags, &mTransactionFlags);
1342edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((old & flags)==0) { // wake the server up
134399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        signalTransaction();
1344edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1345edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return old;
1346edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1347edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1348edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1349b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennisvoid SurfaceFlinger::setTransactionState(const Vector<ComposerState>& state,
135028378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        int orientation, uint32_t flags) {
1351698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
1352cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
135328378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    uint32_t transactionFlags = 0;
1354b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis    if (mCurrentState.orientation != orientation) {
1355b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis        if (uint32_t(orientation)<=eOrientation270 || orientation==42) {
1356b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis            mCurrentState.orientation = orientation;
135728378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis            transactionFlags |= eTransactionNeeded;
1358b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis        } else if (orientation != eOrientationUnchanged) {
135932397c1cd3327905173b36baa6fd1c579bc328ffSteve Block            ALOGW("setTransactionState: ignoring unrecognized orientation: %d",
1360b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis                    orientation);
1361b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis        }
1362b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis    }
1363b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis
1364698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    const size_t count = state.size();
1365698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
1366698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const ComposerState& s(state[i]);
1367698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        sp<Client> client( static_cast<Client *>(s.client.get()) );
136828378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        transactionFlags |= setClientStateLocked(client, s.state);
1369698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    }
1370386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian
137128378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    if (transactionFlags) {
1372386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // this triggers the transaction
137328378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        setTransactionFlags(transactionFlags);
1374698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian
1375386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // if this is a synchronous transaction, wait for it to take effect
1376386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // before returning.
1377386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        if (flags & eSynchronous) {
1378386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            mTransationPending = true;
1379386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        }
1380386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        while (mTransationPending) {
1381386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
1382386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            if (CC_UNLIKELY(err != NO_ERROR)) {
1383386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                // just in case something goes wrong in SF, return to the
1384386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                // called after a few seconds.
138532397c1cd3327905173b36baa6fd1c579bc328ffSteve Block                ALOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!");
1386386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                mTransationPending = false;
1387386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                break;
1388386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            }
1389cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        }
1390edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1391edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1392edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
13930ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopiansp<ISurface> SurfaceFlinger::createSurface(
13940ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        ISurfaceComposerClient::surface_data_t* params,
13950ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const String8& name,
13960ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const sp<Client>& client,
1397edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        DisplayID d, uint32_t w, uint32_t h, PixelFormat format,
1398edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t flags)
1399edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1400076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBaseClient> layer;
1401a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    sp<ISurface> surfaceHandle;
14026e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian
14036e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    if (int32_t(w|h) < 0) {
1404e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE("createSurface() failed, w or h is negative (w=%d, h=%d)",
14056e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian                int(w), int(h));
14066e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian        return surfaceHandle;
14076e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    }
14088b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
1409ff615cc7a1cceedd705b0623b058c54669b29596Mathias Agopian    //ALOGD("createSurface for (%d x %d), name=%s", w, h, name.string());
1410b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<Layer> normalLayer;
1411edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (flags & eFXSurfaceMask) {
1412edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceNormal:
1413a5529c8778c2f407f482fc12165aeb76c0f505c2Mathias Agopian            normalLayer = createNormalSurface(client, d, w, h, flags, format);
1414a5529c8778c2f407f482fc12165aeb76c0f505c2Mathias Agopian            layer = normalLayer;
1415edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
1416edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceBlur:
14171293a8eb567fd63c072a6970fa9dcf37d076059fMathias Agopian            // for now we treat Blur as Dim, until we can implement it
14181293a8eb567fd63c072a6970fa9dcf37d076059fMathias Agopian            // efficiently.
1419edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceDim:
142096f0819f81293076e652792794a961543e6750d7Mathias Agopian            layer = createDimSurface(client, d, w, h, flags);
1421edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
1422118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        case eFXSurfaceScreenshot:
1423118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian            layer = createScreenshotSurface(client, d, w, h, flags);
1424118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian            break;
1425edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1426edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1427076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (layer != 0) {
142896f0819f81293076e652792794a961543e6750d7Mathias Agopian        layer->initStates(w, h, flags);
1429285dbde2e0cd0057be070ded3be8f5f453147edcMathias Agopian        layer->setName(name);
143096f0819f81293076e652792794a961543e6750d7Mathias Agopian        ssize_t token = addClientLayer(client, layer);
1431b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1432edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        surfaceHandle = layer->getSurface();
14338b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber        if (surfaceHandle != 0) {
143496f0819f81293076e652792794a961543e6750d7Mathias Agopian            params->token = token;
1435a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            params->identity = layer->getIdentity();
1436b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            if (normalLayer != 0) {
1437b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian                Mutex::Autolock _l(mStateLock);
1438a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                mLayerMap.add(layer->getSurfaceBinder(), normalLayer);
1439b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            }
14401c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        }
1441b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
144296f0819f81293076e652792794a961543e6750d7Mathias Agopian        setTransactionFlags(eTransactionNeeded);
1443edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1444edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1445edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return surfaceHandle;
1446edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1447edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1448b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<Layer> SurfaceFlinger::createNormalSurface(
1449f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        const sp<Client>& client, DisplayID display,
145096f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags,
14511c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        PixelFormat& format)
1452edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1453edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize the surfaces
1454edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (format) { // TODO: take h/w into account
1455edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSPARENT:
1456edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSLUCENT:
1457edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        format = PIXEL_FORMAT_RGBA_8888;
1458edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1459edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_OPAQUE:
1460a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888
1461a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian        format = PIXEL_FORMAT_RGB_565;
1462a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#else
14638f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian        format = PIXEL_FORMAT_RGBX_8888;
1464a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif
1465edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1466edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1467edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1468a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888
1469a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian    if (format == PIXEL_FORMAT_RGBX_8888)
1470a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian        format = PIXEL_FORMAT_RGBA_8888;
1471a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif
1472a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian
147396f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<Layer> layer = new Layer(this, display, client);
1474f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian    status_t err = layer->setBuffers(w, h, format, flags);
147599ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten    if (CC_LIKELY(err != NO_ERROR)) {
1476e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE("createNormalSurfaceLocked() failed (%s)", strerror(-err));
1477076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        layer.clear();
1478edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1479edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1480edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1481edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1482b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<LayerDim> SurfaceFlinger::createDimSurface(
1483f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        const sp<Client>& client, DisplayID display,
148496f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags)
1485edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
148696f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<LayerDim> layer = new LayerDim(this, display, client);
1487118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    return layer;
1488118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
1489118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
1490118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopiansp<LayerScreenshot> SurfaceFlinger::createScreenshotSurface(
1491118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        const sp<Client>& client, DisplayID display,
1492118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags)
1493118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{
1494118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    sp<LayerScreenshot> layer = new LayerScreenshot(this, display, client);
1495edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1496edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1497edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
149896f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeSurface(const sp<Client>& client, SurfaceID sid)
14999a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
15009a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    /*
15019a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     * called by the window manager, when a surface should be marked for
15029a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     * destruction.
15038b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber     *
15040aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * The surface is removed from the current and drawing lists, but placed
15050aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * in the purgatory queue, so it's not destroyed right-away (we need
15060aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * to wait for all client's references to go away first).
15079a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     */
15089a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
150948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    status_t err = NAME_NOT_FOUND;
15100aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian    Mutex::Autolock _l(mStateLock);
151196f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<LayerBaseClient> layer = client->getLayerUser(sid);
1512b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam
151348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    if (layer != 0) {
151448d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        err = purgatorizeLayer_l(layer);
151548d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        if (err == NO_ERROR) {
151648d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian            setTransactionFlags(eTransactionNeeded);
151748d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        }
15189a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    }
15199a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return err;
15209a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
15219a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
1522ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopianstatus_t SurfaceFlinger::destroySurface(const wp<LayerBaseClient>& layer)
1523edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1524759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian    // called by ~ISurface() when all references are gone
1525ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    status_t err = NO_ERROR;
1526ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    sp<LayerBaseClient> l(layer.promote());
1527ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    if (l != NULL) {
1528ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        Mutex::Autolock _l(mStateLock);
1529ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        err = removeLayer_l(l);
1530ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        if (err == NAME_NOT_FOUND) {
1531ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // The surface wasn't in the current list, which means it was
1532ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // removed already, which means it is in the purgatory,
1533ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // and need to be removed from there.
1534ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            ssize_t idx = mLayerPurgatory.remove(l);
1535e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block            ALOGE_IF(idx < 0,
1536ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian                    "layer=%p is not in the purgatory list", l.get());
1537f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        }
1538e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE_IF(err<0 && err != NAME_NOT_FOUND,
1539ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian                "error removing layer=%p (%s)", l.get(), strerror(-err));
1540ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    }
1541ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    return err;
1542edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1543edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1544698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopianuint32_t SurfaceFlinger::setClientStateLocked(
154596f0819f81293076e652792794a961543e6750d7Mathias Agopian        const sp<Client>& client,
1546698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const layer_state_t& s)
1547edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1548edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t flags = 0;
1549698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    sp<LayerBaseClient> layer(client->getLayerUser(s.surface));
1550698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    if (layer != 0) {
1551698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const uint32_t what = s.what;
1552698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & ePositionChanged) {
1553698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setPosition(s.x, s.y))
1554698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1555698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1556698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eLayerChanged) {
1557698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
1558698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setLayer(s.z)) {
1559698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                mCurrentState.layersSortedByZ.removeAt(idx);
1560698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                mCurrentState.layersSortedByZ.add(layer);
1561698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                // we need traversal (state changed)
1562698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                // AND transaction (list changed)
1563698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTransactionNeeded|eTraversalNeeded;
1564edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1565698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1566698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eSizeChanged) {
1567698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setSize(s.w, s.h)) {
1568698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1569edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1570edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1571698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eAlphaChanged) {
1572698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f)))
1573698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1574698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1575698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eMatrixChanged) {
1576698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setMatrix(s.matrix))
1577698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1578698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1579698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eTransparentRegionChanged) {
1580698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setTransparentRegionHint(s.transparentRegion))
1581698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1582698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1583698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eVisibilityChanged) {
1584698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setFlags(s.flags, s.mask))
1585698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1586698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1587f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        if (what & eCropChanged) {
1588f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis            if (layer->setCrop(s.crop))
1589f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis                flags |= eTraversalNeeded;
1590f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        }
1591edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1592698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    return flags;
1593edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1594edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1595b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// ---------------------------------------------------------------------------
1596b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
1597b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopianvoid SurfaceFlinger::onScreenAcquired() {
15988e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross    ALOGD("Screen about to return, flinger = %p", this);
15991b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    const DisplayHardware& hw(getDefaultDisplayHardware()); // XXX: this should be per DisplayHardware
1600b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    hw.acquireScreen();
160122ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian    mEventThread->onScreenAcquired();
1602b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    // this is a temporary work-around, eventually this should be called
1603b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    // by the power-manager
1604b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    SurfaceFlinger::turnElectronBeamOn(mElectronBeamAnimationMode);
160522ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian    // from this point on, SF will process updates again
16068acce2046ac7086c3dcfb1fc7c9c39f31de48694Mathias Agopian    repaintEverything();
1607edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1608edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1609b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopianvoid SurfaceFlinger::onScreenReleased() {
16108e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross    ALOGD("About to give-up screen, flinger = %p", this);
16111b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    const DisplayHardware& hw(getDefaultDisplayHardware()); // XXX: this should be per DisplayHardware
1612b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    if (hw.isScreenAcquired()) {
161322ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian        mEventThread->onScreenReleased();
1614b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        hw.releaseScreen();
1615b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        // from this point on, SF will stop drawing
1616b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    }
1617b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian}
1618b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
16198e533069e5721e55cb9768e140e16546c3a4a8b6Colin Crossvoid SurfaceFlinger::unblank() {
1620b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    class MessageScreenAcquired : public MessageBase {
1621b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        SurfaceFlinger* flinger;
1622b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    public:
1623b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        MessageScreenAcquired(SurfaceFlinger* flinger) : flinger(flinger) { }
1624b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        virtual bool handler() {
1625b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            flinger->onScreenAcquired();
1626b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            return true;
1627b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        }
1628b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    };
1629b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    sp<MessageBase> msg = new MessageScreenAcquired(this);
1630b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    postMessageSync(msg);
1631edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1632edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
16338e533069e5721e55cb9768e140e16546c3a4a8b6Colin Crossvoid SurfaceFlinger::blank() {
1634b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    class MessageScreenReleased : public MessageBase {
1635b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        SurfaceFlinger* flinger;
1636b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    public:
1637b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        MessageScreenReleased(SurfaceFlinger* flinger) : flinger(flinger) { }
1638b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        virtual bool handler() {
1639b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            flinger->onScreenReleased();
1640b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            return true;
1641b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        }
1642b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    };
1643b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    sp<MessageBase> msg = new MessageScreenReleased(this);
1644b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    postMessageSync(msg);
1645b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian}
1646b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
1647b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// ---------------------------------------------------------------------------
1648b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
1649edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
1650edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
16511d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling    const size_t SIZE = 4096;
1652edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char buffer[SIZE];
1653edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    String8 result;
165499b49840d309727678b77403d6cc9f920111623fMathias Agopian
165599b49840d309727678b77403d6cc9f920111623fMathias Agopian    if (!PermissionCache::checkCallingPermission(sDump)) {
1656edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        snprintf(buffer, SIZE, "Permission Denial: "
1657edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                "can't dump SurfaceFlinger from pid=%d, uid=%d\n",
1658edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                IPCThreadState::self()->getCallingPid(),
1659edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                IPCThreadState::self()->getCallingUid());
1660edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        result.append(buffer);
1661edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
16629795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // Try to get the main lock, but don't insist if we can't
16639795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // (this would indicate SF is stuck, but we want to be able to
16649795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // print something in dumpsys).
16659795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        int retry = 3;
16669795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        while (mStateLock.tryLock()<0 && --retry>=0) {
16679795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            usleep(1000000);
16689795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
16699795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const bool locked(retry >= 0);
16709795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (!locked) {
16718b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber            snprintf(buffer, SIZE,
16729795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "SurfaceFlinger appears to be unresponsive, "
16739795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "dumping anyways (no locks held)\n");
16749795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            result.append(buffer);
16759795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
16769795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
167782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        bool dumpAll = true;
167882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        size_t index = 0;
167925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        size_t numArgs = args.size();
168025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        if (numArgs) {
168125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
168225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--list"))) {
168325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                index++;
168425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                listLayersLocked(args, index, result, buffer, SIZE);
168535aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
168625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            }
168725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
168825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
168925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--latency"))) {
169082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                index++;
169182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                dumpStatsLocked(args, index, result, buffer, SIZE);
169235aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
169382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            }
169425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
169525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
169625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--latency-clear"))) {
169725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                index++;
169825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                clearStatsLocked(args, index, result, buffer, SIZE);
169935aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
170025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            }
1701edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
17021b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
170382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (dumpAll) {
170482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            dumpAllLocked(result, buffer, SIZE);
170582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
170648b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
170782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (locked) {
170882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mStateLock.unlock();
170948b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        }
171082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
171182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    write(fd, result.string(), result.size());
171282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    return NO_ERROR;
171382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
171448b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
171525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::listLayersLocked(const Vector<String16>& args, size_t& index,
171625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        String8& result, char* buffer, size_t SIZE) const
171725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
171825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
171925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const size_t count = currentLayers.size();
172025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
172125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
172225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        snprintf(buffer, SIZE, "%s\n", layer->getName().string());
172325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        result.append(buffer);
172425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
172525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
172625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
172782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index,
172882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        String8& result, char* buffer, size_t SIZE) const
172982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
173082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    String8 name;
173182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    if (index < args.size()) {
173282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        name = String8(args[index]);
173382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        index++;
173482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
173548b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
173682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
173782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const size_t count = currentLayers.size();
173882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    for (size_t i=0 ; i<count ; i++) {
173982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
174082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (name.isEmpty()) {
174182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            snprintf(buffer, SIZE, "%s\n", layer->getName().string());
174282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            result.append(buffer);
174382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
174482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (name.isEmpty() || (name == layer->getName())) {
174582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            layer->dumpStats(result, buffer, SIZE);
174682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
174782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
174882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
1749ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian
175025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& index,
175125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        String8& result, char* buffer, size_t SIZE) const
175225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
175325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    String8 name;
175425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    if (index < args.size()) {
175525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        name = String8(args[index]);
175625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        index++;
175725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
175825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
175925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
176025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const size_t count = currentLayers.size();
176125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
176225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
176325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        if (name.isEmpty() || (name == layer->getName())) {
176425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            layer->clearStats();
176525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        }
176625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
176725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
176825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
176982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpAllLocked(
177082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        String8& result, char* buffer, size_t SIZE) const
177182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
177282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    // figure out if we're stuck somewhere
177382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t now = systemTime();
177482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t inSwapBuffers(mDebugInSwapBuffers);
177582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t inTransaction(mDebugInTransaction);
177682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0;
177782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0;
1778bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
177982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
178082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump the visible layer list
178182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
178282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
178382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const size_t count = currentLayers.size();
178482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "Visible layers (count = %d)\n", count);
178582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
178682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    for (size_t i=0 ; i<count ; i++) {
178782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
178882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        layer->dump(result, buffer, SIZE);
178982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
1790bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
179182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
179282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump the layers in the purgatory
179382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
1794ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian
179582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const size_t purgatorySize = mLayerPurgatory.size();
179682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "Purgatory state (%d entries)\n", purgatorySize);
179782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
179882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    for (size_t i=0 ; i<purgatorySize ; i++) {
179982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
180082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        layer->shortDump(result, buffer, SIZE);
180182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
18021b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
180382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
180482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump SurfaceFlinger global state
180582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
18061b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
180782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "SurfaceFlinger global state:\n");
180882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
18091b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
18101b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    const DisplayHardware& hw(getDefaultDisplayHardware());
181182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const GLExtensions& extensions(GLExtensions::getInstance());
181282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "GLES: %s, %s, %s\n",
181382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            extensions.getVendor(),
181482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            extensions.getRenderer(),
181582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            extensions.getVersion());
181682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
1817d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
181882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "EGL : %s\n",
18191b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian            eglQueryString(hw.getEGLDisplay(),
182082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                    EGL_VERSION_HW_ANDROID));
182182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
182273d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian
182382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "EXTS: %s\n", extensions.getExtension());
182482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
18259795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
182682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    mWormholeRegion.dump(result, "WormholeRegion");
182782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE,
182882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  orientation=%d, canDraw=%d\n",
182982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mCurrentState.orientation, hw.canDraw());
183082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
183182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE,
183282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  last eglSwapBuffers() time: %f us\n"
183382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  last transaction time     : %f us\n"
1834c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian            "  transaction-flags         : %08x\n"
183582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  refresh-rate              : %f fps\n"
183682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  x-dpi                     : %f\n"
1837b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian            "  y-dpi                     : %f\n"
1838b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian            "  density                   : %f\n",
183982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mLastSwapBufferTime/1000.0,
184082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mLastTransactionTime/1000.0,
1841c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian            mTransactionFlags,
184282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            hw.getRefreshRate(),
184382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            hw.getDpiX(),
1844b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian            hw.getDpiY(),
1845b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian            hw.getDensity());
184682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
184782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
184882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "  eglSwapBuffers time: %f us\n",
184982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            inSwapBuffersDuration/1000.0);
185082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
185182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
185282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "  transaction time: %f us\n",
185382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            inTransactionDuration/1000.0);
185482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
185582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
185682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
185782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * VSYNC state
185882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
185982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    mEventThread->dump(result, buffer, SIZE);
186082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
186182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
186282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump HWComposer state
186382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
186482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    HWComposer& hwc(hw.getHwComposer());
186582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "h/w composer state:\n");
186682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
186782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "  h/w composer %s and %s\n",
186882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            hwc.initCheck()==NO_ERROR ? "present" : "not present",
186982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                    (mDebugDisableHWC || mDebugRegion) ? "disabled" : "enabled");
187082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
18713b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    hwc.dump(result, buffer, SIZE, hw.getVisibleLayersSortedByZ());
187282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
187382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
187482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump gralloc state
187582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
187682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
187782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    alloc.dump(result);
187882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    hw.dump(result);
1879edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1880edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1881edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::onTransact(
1882edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
1883edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1884edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (code) {
1885edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case CREATE_CONNECTION:
1886698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        case SET_TRANSACTION_STATE:
1887edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case SET_ORIENTATION:
1888edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case BOOT_FINISHED:
188959119e658a12279e8fff508f8773843de2d90917Mathias Agopian        case TURN_ELECTRON_BEAM_OFF:
18909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        case TURN_ELECTRON_BEAM_ON:
18918e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross        case BLANK:
18928e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross        case UNBLANK:
1893edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        {
1894edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // codes that require permission check
1895edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            IPCThreadState* ipc = IPCThreadState::self();
1896edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int pid = ipc->getCallingPid();
1897a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian            const int uid = ipc->getCallingUid();
189899b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
189999b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) {
1900e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block                ALOGE("Permission Denial: "
1901375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                        "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
1902375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                return PERMISSION_DENIED;
1903edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
19041b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
19051b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
19061b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        case CAPTURE_SCREEN:
19071b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
19081b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            // codes that require permission check
19091b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
19101b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int pid = ipc->getCallingPid();
19111b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int uid = ipc->getCallingUid();
191299b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
191399b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) {
1914e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block                ALOGE("Permission Denial: "
19151b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                        "can't read framebuffer pid=%d, uid=%d", pid, uid);
19161b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                return PERMISSION_DENIED;
19171b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            }
19181b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
1919edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1920edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
19211b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
1922edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
1923edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
1924b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        CHECK_INTERFACE(ISurfaceComposer, data, reply);
192599ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten        if (CC_UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) {
1926375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
1927375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int pid = ipc->getCallingPid();
1928375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int uid = ipc->getCallingUid();
1929e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block            ALOGE("Permission Denial: "
1930375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                    "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
1931edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return PERMISSION_DENIED;
1932edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1933edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int n;
1934edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        switch (code) {
193501b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian            case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE
193635b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian            case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE
1937edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1938edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1002:  // SHOW_UPDATES
1939edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                n = data.readInt32();
1940edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDebugRegion = n ? n : (mDebugRegion ? 0 : 1);
194153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
194253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
1943edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1944edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1004:{ // repaint everything
194553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
1946cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
1947cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            }
1948cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            case 1005:{ // force transaction
1949cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
1950cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
1951edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
19524d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            case 1006:{ // send empty update
19534d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian                signalRefresh();
19544d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian                return NO_ERROR;
19554d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            }
195653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian            case 1008:  // toggle use of hw composer
195753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                n = data.readInt32();
195853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                mDebugDisableHWC = n ? 1 : 0;
195953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
196053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
196153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                return NO_ERROR;
1962a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian            case 1009:  // toggle use of transform hint
1963a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                n = data.readInt32();
1964a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                mDebugDisableTransformHint = n ? 1 : 0;
1965a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                invalidateHwcGeometry();
1966a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                repaintEverything();
1967a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                return NO_ERROR;
1968edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1010:  // interrogate.
196901b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian                reply->writeInt32(0);
1970edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(0);
1971edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(mDebugRegion);
1972b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                reply->writeInt32(0);
197312839bee29bdcc65731b4d42029cc59e2320c5c4Dianne Hackborn                reply->writeInt32(mDebugDisableHWC);
1974edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1975edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1013: {
1976edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                Mutex::Autolock _l(mStateLock);
19771b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian                const DisplayHardware& hw(getDefaultDisplayHardware());
1978edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(hw.getPageFlipCount());
1979edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1980edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return NO_ERROR;
1981edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1982edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1983edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return err;
1984edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1985edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
198653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopianvoid SurfaceFlinger::repaintEverything() {
19871b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    const DisplayHardware& hw(getDefaultDisplayHardware()); // FIXME: this cannot be bound the default display
19880dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    const Rect bounds(hw.getBounds());
19890dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    setInvalidateRegion(Region(bounds));
199099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    signalTransaction();
199153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian}
199253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian
19930dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopianvoid SurfaceFlinger::setInvalidateRegion(const Region& reg) {
19940dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    Mutex::Autolock _l(mInvalidateLock);
19950dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    mInvalidateRegion = reg;
19960dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian}
19970dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian
19980dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias AgopianRegion SurfaceFlinger::getAndClearInvalidateRegion() {
19990dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    Mutex::Autolock _l(mInvalidateLock);
20000dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    Region reg(mInvalidateRegion);
20010dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    mInvalidateRegion.clear();
20020dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    return reg;
20030dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian}
20040dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian
200559119e658a12279e8fff508f8773843de2d90917Mathias Agopian// ---------------------------------------------------------------------------
200659119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2007118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopianstatus_t SurfaceFlinger::renderScreenToTexture(DisplayID dpy,
2008118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        GLuint* textureName, GLfloat* uOut, GLfloat* vOut)
2009118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{
2010118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    Mutex::Autolock _l(mStateLock);
2011118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    return renderScreenToTextureLocked(dpy, textureName, uOut, vOut);
2012118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
2013118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
20149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::renderScreenToTextureLocked(DisplayID dpy,
20159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        GLuint* textureName, GLfloat* uOut, GLfloat* vOut)
201659119e658a12279e8fff508f8773843de2d90917Mathias Agopian{
201722ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian    ATRACE_CALL();
201822ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian
201959119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
202059119e658a12279e8fff508f8773843de2d90917Mathias Agopian        return INVALID_OPERATION;
202159119e658a12279e8fff508f8773843de2d90917Mathias Agopian
202259119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // get screen geometry
20231b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    const DisplayHardware& hw(getDisplayHardware(dpy));
202459119e658a12279e8fff508f8773843de2d90917Mathias Agopian    const uint32_t hw_w = hw.getWidth();
202559119e658a12279e8fff508f8773843de2d90917Mathias Agopian    const uint32_t hw_h = hw.getHeight();
202659119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLfloat u = 1;
202759119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLfloat v = 1;
202859119e658a12279e8fff508f8773843de2d90917Mathias Agopian
202959119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // make sure to clear all GL error flags
203059119e658a12279e8fff508f8773843de2d90917Mathias Agopian    while ( glGetError() != GL_NO_ERROR ) ;
203159119e658a12279e8fff508f8773843de2d90917Mathias Agopian
203259119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // create a FBO
203359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLuint name, tname;
203459119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glGenTextures(1, &tname);
203559119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
2036a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2037a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
20389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
20399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            hw_w, hw_h, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
204059119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (glGetError() != GL_NO_ERROR) {
2041015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian        while ( glGetError() != GL_NO_ERROR ) ;
204259119e658a12279e8fff508f8773843de2d90917Mathias Agopian        GLint tw = (2 << (31 - clz(hw_w)));
204359119e658a12279e8fff508f8773843de2d90917Mathias Agopian        GLint th = (2 << (31 - clz(hw_h)));
20449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
20459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian                tw, th, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
204659119e658a12279e8fff508f8773843de2d90917Mathias Agopian        u = GLfloat(hw_w) / tw;
204759119e658a12279e8fff508f8773843de2d90917Mathias Agopian        v = GLfloat(hw_h) / th;
204859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    }
204959119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glGenFramebuffersOES(1, &name);
205059119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
20519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES,
20529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0);
205359119e658a12279e8fff508f8773843de2d90917Mathias Agopian
20549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // redraw the screen entirely...
2055c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_EXTERNAL_OES);
2056c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_2D);
20579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glClearColor(0,0,0,1);
20589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glClear(GL_COLOR_BUFFER_BIT);
2059a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glMatrixMode(GL_MODELVIEW);
2060a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glLoadIdentity();
20613b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    const Vector< sp<LayerBase> >& layers(hw.getVisibleLayersSortedByZ());
20629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const size_t count = layers.size();
20639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (size_t i=0 ; i<count ; ++i) {
20649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
20651b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian        layer->drawForSreenShot(hw);
20669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
206759119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2068118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    hw.compositionComplete();
2069118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
20709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // back to main framebuffer
20719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
20729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDeleteFramebuffersOES(1, &name);
207359119e658a12279e8fff508f8773843de2d90917Mathias Agopian
20749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *textureName = tname;
20759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *uOut = u;
20769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *vOut = v;
20779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
20789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
207959119e658a12279e8fff508f8773843de2d90917Mathias Agopian
20809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// ---------------------------------------------------------------------------
208159119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2082ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopianclass VSyncWaiter {
2083ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    DisplayEventReceiver::Event buffer[4];
2084ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    sp<Looper> looper;
2085ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    sp<IDisplayEventConnection> events;
2086ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    sp<BitTube> eventTube;
2087ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopianpublic:
2088ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    VSyncWaiter(const sp<EventThread>& eventThread) {
2089ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        looper = new Looper(true);
2090ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        events = eventThread->createEventConnection();
2091ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        eventTube = events->getDataChannel();
2092ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        looper->addFd(eventTube->getFd(), 0, ALOOPER_EVENT_INPUT, 0, 0);
2093ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        events->requestNextVsync();
2094ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    }
2095ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
2096ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    void wait() {
2097ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        ssize_t n;
2098ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
2099ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        looper->pollOnce(-1);
2100ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        // we don't handle any errors here, it doesn't matter
2101ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        // and we don't want to take the risk to get stuck.
2102ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
2103ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        // drain the events...
2104ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        while ((n = DisplayEventReceiver::getEvents(
2105ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian                eventTube, buffer, 4)) > 0) ;
2106ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
2107ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        events->requestNextVsync();
2108ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    }
2109ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian};
2110ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
21119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::electronBeamOffAnimationImplLocked()
21129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
21139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // get screen geometry
21141b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    const DisplayHardware& hw(getDefaultDisplayHardware());
21159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_w = hw.getWidth();
21169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_h = hw.getHeight();
2117a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    const Region screenBounds(hw.getBounds());
211859119e658a12279e8fff508f8773843de2d90917Mathias Agopian
21199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat u, v;
21209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLuint tname;
2121118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    status_t result = renderScreenToTextureLocked(0, &tname, &u, &v);
21229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (result != NO_ERROR) {
21239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return result;
21249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
212559119e658a12279e8fff508f8773843de2d90917Mathias Agopian
21269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat vtx[8];
2127a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    const GLfloat texCoords[4][2] = { {0,0}, {0,v}, {u,v}, {u,0} };
21289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
21299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
21309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
21319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2132b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2133b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
21349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
21359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
21369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glVertexPointer(2, GL_FLOAT, 0, vtx);
21379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2138ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    /*
2139ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     * Texture coordinate mapping
2140ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *
2141ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *                 u
2142ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *    1 +----------+---+
2143ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |     |    |   |  image is inverted
2144ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |     V    |   |  w.r.t. the texture
2145ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *  1-v +----------+   |  coordinates
2146ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |              |
2147ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |              |
2148ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |              |
2149ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *    0 +--------------+
2150ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      0              1
2151ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *
2152ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     */
2153ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian
21549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class s_curve_interpolator {
21559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float nbFrames, s, v;
21569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
21579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        s_curve_interpolator(int nbFrames, float s)
21589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : nbFrames(1.0f / (nbFrames-1)), s(s),
21599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian          v(1.0f + expf(-s + 0.5f*s)) {
21609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
21619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float operator()(int f) {
21629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const float x = f * nbFrames;
21639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f;
21649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
21659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
21669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class v_stretch {
21689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
21699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
21709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        v_stretch(uint32_t hw_w, uint32_t hw_h)
21719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
21729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
21739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
21749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w + (hw_w * v);
21759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = hw_h - (hw_h * v);
21769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
21779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
2178ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[0] = x;         vtx[1] = y;
2179ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
2180ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
2181ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
21829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
21839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
21849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class h_stretch {
21869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
21879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
21889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        h_stretch(uint32_t hw_w, uint32_t hw_h)
21899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
219059119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
21919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
21929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w - (hw_w * v);
21939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = 1.0f;
21949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
21959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
2196ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[0] = x;         vtx[1] = y;
2197ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
2198ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
2199ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
22009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
22019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
22029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2203ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    VSyncWaiter vsync(mEventThread);
2204ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
22059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // the full animation is 24 frames
2206ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    char value[PROPERTY_VALUE_MAX];
2207ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    property_get("debug.sf.electron_frames", value, "24");
2208ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    int nbFrames = (atoi(value) + 1) >> 1;
2209ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    if (nbFrames <= 0) // just in case
2210ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian        nbFrames = 24;
2211ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian
22129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itr(nbFrames, 7.5f);
22139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itg(nbFrames, 8.0f);
22149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itb(nbFrames, 8.5f);
22159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    v_stretch vverts(hw_w, hw_h);
2217a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian
2218a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glMatrixMode(GL_TEXTURE);
2219a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glLoadIdentity();
2220a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glMatrixMode(GL_MODELVIEW);
2221a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glLoadIdentity();
2222a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian
22239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnable(GL_BLEND);
22249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBlendFunc(GL_ONE, GL_ONE);
22259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=0 ; i<nbFrames ; i++) {
22269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float x, y, w, h;
22279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vr = itr(i);
22289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vg = itg(i);
22299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vb = itb(i);
22309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2231ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        // wait for vsync
2232ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        vsync.wait();
2233ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
22349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // clear screen
22359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(1,1,1,1);
22369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
22379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glEnable(GL_TEXTURE_2D);
223859119e658a12279e8fff508f8773843de2d90917Mathias Agopian
22399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the red plane
22409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vr);
22419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(1,0,0,1);
22429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
22439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the green plane
22459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vg);
22469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,1,0,1);
22479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
22489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the blue plane
22509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vb);
22519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,0,1,1);
22529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
22539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the white highlight (we use the last vertices)
225559119e658a12279e8fff508f8773843de2d90917Mathias Agopian        glDisable(GL_TEXTURE_2D);
225659119e658a12279e8fff508f8773843de2d90917Mathias Agopian        glColorMask(1,1,1,1);
22579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColor4f(vg, vg, vg, 1);
22589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
22599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
22609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
22619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    h_stretch hverts(hw_w, hw_h);
22639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_BLEND);
22649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_TEXTURE_2D);
22659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
22669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=0 ; i<nbFrames ; i++) {
22679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float v = itg(i);
22689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hverts(vtx, v);
2269ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
2270ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        // wait for vsync
2271ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        vsync.wait();
2272ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
22739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
22749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColor4f(1-v, 1-v, 1-v, 1);
22759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
22769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
22779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
22789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
22809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
22819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDeleteTextures(1, &tname);
2282a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    glDisable(GL_TEXTURE_2D);
2283c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_BLEND);
22849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
22859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
22869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::electronBeamOnAnimationImplLocked()
22889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
22899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    status_t result = PERMISSION_DENIED;
22909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
22929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return INVALID_OPERATION;
22939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // get screen geometry
22961b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    const DisplayHardware& hw(getDefaultDisplayHardware());
22979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_w = hw.getWidth();
22989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_h = hw.getHeight();
22999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const Region screenBounds(hw.bounds());
23009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
23019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat u, v;
23029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLuint tname;
23039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    result = renderScreenToTextureLocked(0, &tname, &u, &v);
23049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (result != NO_ERROR) {
23059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return result;
23069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
23079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
23089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat vtx[8];
23099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const GLfloat texCoords[4][2] = { {0,v}, {0,0}, {u,0}, {u,v} };
23109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
23119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
23129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
23139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2314b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2315b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
23169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
23179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
23189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glVertexPointer(2, GL_FLOAT, 0, vtx);
23199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
23209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class s_curve_interpolator {
23219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float nbFrames, s, v;
23229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
23239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        s_curve_interpolator(int nbFrames, float s)
23249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : nbFrames(1.0f / (nbFrames-1)), s(s),
23259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian          v(1.0f + expf(-s + 0.5f*s)) {
23269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
23279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float operator()(int f) {
23289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const float x = f * nbFrames;
23299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f;
23309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
23319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
23329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
23339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class v_stretch {
23349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
23359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
23369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        v_stretch(uint32_t hw_w, uint32_t hw_h)
23379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
233859119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
23399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
23409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w + (hw_w * v);
23419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = hw_h - (hw_h * v);
23429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
23439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
23449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[0] = x;         vtx[1] = y;
23459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
23469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
23479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
23489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
23499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
23509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
23519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class h_stretch {
23529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
23539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
23549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        h_stretch(uint32_t hw_w, uint32_t hw_h)
23559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
23569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
23579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
23589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w - (hw_w * v);
23599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = 1.0f;
23609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
23619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
23629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[0] = x;         vtx[1] = y;
23639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
23649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
23659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
23669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
23679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
23689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2369ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    VSyncWaiter vsync(mEventThread);
2370ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
2371a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian    // the full animation is 12 frames
2372a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian    int nbFrames = 8;
23739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itr(nbFrames, 7.5f);
23749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itg(nbFrames, 8.0f);
23759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itb(nbFrames, 8.5f);
23769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
23779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    h_stretch hverts(hw_w, hw_h);
23789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_BLEND);
23799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_TEXTURE_2D);
23809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
23819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=nbFrames-1 ; i>=0 ; i--) {
23829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float v = itg(i);
23839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hverts(vtx, v);
2384ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
2385ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        // wait for vsync
2386ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        vsync.wait();
2387ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
23889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
23899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColor4f(1-v, 1-v, 1-v, 1);
23909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
23919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
23929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
23939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2394a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian    nbFrames = 4;
23959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    v_stretch vverts(hw_w, hw_h);
23969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnable(GL_BLEND);
23979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBlendFunc(GL_ONE, GL_ONE);
23989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=nbFrames-1 ; i>=0 ; i--) {
23999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float x, y, w, h;
24009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vr = itr(i);
24019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vg = itg(i);
24029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vb = itb(i);
240359119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2404ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        // wait for vsync
2405ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        vsync.wait();
2406ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
24079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // clear screen
240859119e658a12279e8fff508f8773843de2d90917Mathias Agopian        glColorMask(1,1,1,1);
24099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
24109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glEnable(GL_TEXTURE_2D);
24119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
24129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the red plane
24139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vr);
24149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(1,0,0,1);
24159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
24169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
24179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the green plane
24189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vg);
24199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,1,0,1);
24209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
24219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
24229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the blue plane
24239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vb);
24249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,0,1,1);
24259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
24269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
24279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
242859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    }
242959119e658a12279e8fff508f8773843de2d90917Mathias Agopian
24309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
24319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
243259119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glDeleteTextures(1, &tname);
2433a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    glDisable(GL_TEXTURE_2D);
2434c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_BLEND);
243559119e658a12279e8fff508f8773843de2d90917Mathias Agopian
24369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
24379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
24389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
24399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// ---------------------------------------------------------------------------
24409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2441abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOffImplLocked(int32_t mode)
24429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
244322ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian    ATRACE_CALL();
244422ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian
24451b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    DisplayHardware& hw(const_cast<DisplayHardware&>(getDefaultDisplayHardware()));
24469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (!hw.canDraw()) {
24479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // we're already off
24489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return NO_ERROR;
24499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
24507ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian
24517ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian    // turn off hwc while we're doing the animation
24527ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian    hw.getHwComposer().disable();
24537ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian    // and make sure to turn it back on (if needed) next time we compose
24547ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian    invalidateHwcGeometry();
24557ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian
2456abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    if (mode & ISurfaceComposer::eElectronBeamAnimationOff) {
2457abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        electronBeamOffAnimationImplLocked();
2458abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    }
2459abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian
2460abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    // always clear the whole screen at the end of the animation
2461abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    glClearColor(0,0,0,1);
2462abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    glClear(GL_COLOR_BUFFER_BIT);
2463abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    hw.flip( Region(hw.bounds()) );
2464abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian
2465015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian    return NO_ERROR;
246659119e658a12279e8fff508f8773843de2d90917Mathias Agopian}
246759119e658a12279e8fff508f8773843de2d90917Mathias Agopian
246859119e658a12279e8fff508f8773843de2d90917Mathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOff(int32_t mode)
246959119e658a12279e8fff508f8773843de2d90917Mathias Agopian{
247059119e658a12279e8fff508f8773843de2d90917Mathias Agopian    class MessageTurnElectronBeamOff : public MessageBase {
247159119e658a12279e8fff508f8773843de2d90917Mathias Agopian        SurfaceFlinger* flinger;
2472abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        int32_t mode;
247359119e658a12279e8fff508f8773843de2d90917Mathias Agopian        status_t result;
247459119e658a12279e8fff508f8773843de2d90917Mathias Agopian    public:
2475abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        MessageTurnElectronBeamOff(SurfaceFlinger* flinger, int32_t mode)
2476abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            : flinger(flinger), mode(mode), result(PERMISSION_DENIED) {
247759119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
247859119e658a12279e8fff508f8773843de2d90917Mathias Agopian        status_t getResult() const {
247959119e658a12279e8fff508f8773843de2d90917Mathias Agopian            return result;
248059119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
248159119e658a12279e8fff508f8773843de2d90917Mathias Agopian        virtual bool handler() {
248259119e658a12279e8fff508f8773843de2d90917Mathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
2483abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            result = flinger->turnElectronBeamOffImplLocked(mode);
248459119e658a12279e8fff508f8773843de2d90917Mathias Agopian            return true;
248559119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
248659119e658a12279e8fff508f8773843de2d90917Mathias Agopian    };
248759119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2488abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    sp<MessageBase> msg = new MessageTurnElectronBeamOff(this, mode);
248959119e658a12279e8fff508f8773843de2d90917Mathias Agopian    status_t res = postMessageSync(msg);
249059119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (res == NO_ERROR) {
249159119e658a12279e8fff508f8773843de2d90917Mathias Agopian        res = static_cast<MessageTurnElectronBeamOff*>( msg.get() )->getResult();
24929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
24939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // work-around: when the power-manager calls us we activate the
24949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // animation. eventually, the "on" animation will be called
24959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // by the power-manager itself
2496abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        mElectronBeamAnimationMode = mode;
249759119e658a12279e8fff508f8773843de2d90917Mathias Agopian    }
249859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    return res;
249959119e658a12279e8fff508f8773843de2d90917Mathias Agopian}
250059119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2501edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
2502edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2503abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOnImplLocked(int32_t mode)
25049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
25051b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    DisplayHardware& hw(const_cast<DisplayHardware&>(getDefaultDisplayHardware()));
25069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (hw.canDraw()) {
25079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // we're already on
25089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return NO_ERROR;
25099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
2510abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    if (mode & ISurfaceComposer::eElectronBeamAnimationOn) {
2511abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        electronBeamOnAnimationImplLocked();
2512abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    }
2513a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian
2514a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian    // make sure to redraw the whole screen when the animation is done
2515a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian    mDirtyRegion.set(hw.bounds());
251699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    signalTransaction();
2517a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian
2518015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian    return NO_ERROR;
25199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
25209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
25219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOn(int32_t mode)
25229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
25239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class MessageTurnElectronBeamOn : public MessageBase {
25249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        SurfaceFlinger* flinger;
2525abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        int32_t mode;
25269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        status_t result;
25279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
2528abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        MessageTurnElectronBeamOn(SurfaceFlinger* flinger, int32_t mode)
2529abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            : flinger(flinger), mode(mode), result(PERMISSION_DENIED) {
25309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
25319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        status_t getResult() const {
25329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return result;
25339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
25349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        virtual bool handler() {
25359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
2536abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            result = flinger->turnElectronBeamOnImplLocked(mode);
25379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return true;
25389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
25399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
25409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2541abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    postMessageAsync( new MessageTurnElectronBeamOn(this, mode) );
25429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
25439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
25449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
25459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// ---------------------------------------------------------------------------
25469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
254774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopianstatus_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy,
254874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        sp<IMemoryHeap>* heap,
254974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t* w, uint32_t* h, PixelFormat* f,
2550bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t sw, uint32_t sh,
2551bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ, uint32_t maxLayerZ)
255274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{
2553fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian    ATRACE_CALL();
2554fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian
255574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    status_t result = PERMISSION_DENIED;
255674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
255774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // only one display supported for now
25583b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    if (CC_UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) {
255974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return BAD_VALUE;
25603b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
256174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
25623b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject()) {
256374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return INVALID_OPERATION;
25643b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
256574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
256674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // get screen geometry
25671b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    const DisplayHardware& hw(getDisplayHardware(dpy));
256874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const uint32_t hw_w = hw.getWidth();
256974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const uint32_t hw_h = hw.getHeight();
257074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
25713b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    // if we have secure windows on this display, never allow the screen capture
25723b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    if (hw.getSecureLayerVisible()) {
25733b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        return PERMISSION_DENIED;
25743b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
25753b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
25763b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    if ((sw > hw_w) || (sh > hw_h)) {
257774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return BAD_VALUE;
25783b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
257974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
258074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    sw = (!sw) ? hw_w : sw;
258174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    sh = (!sh) ? hw_h : sh;
258274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const size_t size = sw * sh * 4;
258374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
25849d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block    //ALOGD("screenshot: sw=%d, sh=%d, minZ=%d, maxZ=%d",
25851c71a47a6db679a3212f0c99e14f330d6da500faMathias Agopian    //        sw, sh, minLayerZ, maxLayerZ);
2586c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
258774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // make sure to clear all GL error flags
258874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    while ( glGetError() != GL_NO_ERROR ) ;
258974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
259074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // create a FBO
259174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    GLuint name, tname;
259274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glGenRenderbuffersOES(1, &tname);
259374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindRenderbufferOES(GL_RENDERBUFFER_OES, tname);
259474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA8_OES, sw, sh);
2595fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian
259674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glGenFramebuffersOES(1, &name);
259774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
259874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES,
259974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, tname);
260074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
260174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
2602c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
260374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    if (status == GL_FRAMEBUFFER_COMPLETE_OES) {
260474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
260574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // invert everything, b/c glReadPixel() below will invert the FB
260674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glViewport(0, 0, sw, sh);
260774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_PROJECTION);
260874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glPushMatrix();
260974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glLoadIdentity();
2610ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian        glOrthof(0, hw_w, hw_h, 0, 0, 1);
261174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_MODELVIEW);
261274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
261374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // redraw the screen entirely...
261474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glClearColor(0,0,0,1);
261574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
2616f653b897a449e10d6cbfb6e0812f7b0bb02d6482Mathias Agopian
26179575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        const LayerVector& layers(mDrawingState.layersSortedByZ);
26189575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        const size_t count = layers.size();
261974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        for (size_t i=0 ; i<count ; ++i) {
262074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            const sp<LayerBase>& layer(layers[i]);
2621b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian            const uint32_t flags = layer->drawingState().flags;
2622b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian            if (!(flags & ISurfaceComposer::eLayerHidden)) {
2623b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                const uint32_t z = layer->drawingState().z;
2624b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                if (z >= minLayerZ && z <= maxLayerZ) {
26251b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian                    layer->drawForSreenShot(hw);
2626b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                }
2627bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian            }
262874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        }
262974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
263074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // check for errors and return screen capture
263174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        if (glGetError() != GL_NO_ERROR) {
263274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // error while rendering
263374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            result = INVALID_OPERATION;
263474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        } else {
263574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // allocate shared memory large enough to hold the
263674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // screen capture
263774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            sp<MemoryHeapBase> base(
263874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    new MemoryHeapBase(size, 0, "screen-capture") );
263974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            void* const ptr = base->getBase();
264074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            if (ptr) {
264174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                // capture the screen with glReadPixels()
2642fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian                ScopedTrace _t(ATRACE_TAG, "glReadPixels");
264374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                glReadPixels(0, 0, sw, sh, GL_RGBA, GL_UNSIGNED_BYTE, ptr);
264474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                if (glGetError() == GL_NO_ERROR) {
264574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *heap = base;
264674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *w = sw;
264774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *h = sh;
264874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *f = PIXEL_FORMAT_RGBA_8888;
264974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    result = NO_ERROR;
265074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                }
265174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            } else {
265274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                result = NO_MEMORY;
265374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            }
265474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        }
265574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glViewport(0, 0, hw_w, hw_h);
265674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_PROJECTION);
265774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glPopMatrix();
265874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_MODELVIEW);
265974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    } else {
266074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        result = BAD_VALUE;
266174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    }
266274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
266374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // release FBO resources
266474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
266574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glDeleteRenderbuffersOES(1, &tname);
266674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glDeleteFramebuffersOES(1, &name);
2667e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian
2668e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian    hw.compositionComplete();
2669e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian
26709d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block    // ALOGD("screenshot: result = %s", result<0 ? strerror(result) : "OK");
2671c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
267274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    return result;
267374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian}
267474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
267574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
26761b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopianstatus_t SurfaceFlinger::captureScreen(DisplayID dpy,
26771b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        sp<IMemoryHeap>* heap,
267874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t* width, uint32_t* height, PixelFormat* format,
2679bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t sw, uint32_t sh,
2680bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ, uint32_t maxLayerZ)
26811b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian{
26821b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    // only one display supported for now
268399ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten    if (CC_UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
26841b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        return BAD_VALUE;
26851b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
26861b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
26871b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        return INVALID_OPERATION;
26881b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
26891b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    class MessageCaptureScreen : public MessageBase {
26901b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        SurfaceFlinger* flinger;
26911b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        DisplayID dpy;
26921b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        sp<IMemoryHeap>* heap;
26931b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        uint32_t* w;
26941b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        uint32_t* h;
26951b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        PixelFormat* f;
269674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t sw;
269774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t sh;
2698bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ;
2699bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t maxLayerZ;
27001b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        status_t result;
27011b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    public:
27021b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        MessageCaptureScreen(SurfaceFlinger* flinger, DisplayID dpy,
270374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                sp<IMemoryHeap>* heap, uint32_t* w, uint32_t* h, PixelFormat* f,
2704bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                uint32_t sw, uint32_t sh,
2705bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                uint32_t minLayerZ, uint32_t maxLayerZ)
27061b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            : flinger(flinger), dpy(dpy),
2707bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              heap(heap), w(w), h(h), f(f), sw(sw), sh(sh),
2708bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              minLayerZ(minLayerZ), maxLayerZ(maxLayerZ),
2709bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              result(PERMISSION_DENIED)
27101b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
27111b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
27121b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        status_t getResult() const {
27131b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            return result;
27141b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
27151b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        virtual bool handler() {
27161b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
271774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            result = flinger->captureScreenImplLocked(dpy,
2718bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                    heap, w, h, f, sw, sh, minLayerZ, maxLayerZ);
27191b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            return true;
27201b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
27211b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    };
27221b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
27231b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    sp<MessageBase> msg = new MessageCaptureScreen(this,
2724bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian            dpy, heap, width, height, format, sw, sh, minLayerZ, maxLayerZ);
27251b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    status_t res = postMessageSync(msg);
27261b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    if (res == NO_ERROR) {
27271b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        res = static_cast<MessageCaptureScreen*>( msg.get() )->getResult();
27281b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    }
27291b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    return res;
27301b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian}
27311b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
27321b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// ---------------------------------------------------------------------------
27331b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
2734b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<Layer> SurfaceFlinger::getLayer(const sp<ISurface>& sur) const
2735edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2736b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<Layer> result;
2737b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    Mutex::Autolock _l(mStateLock);
2738b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    result = mLayerMap.valueFor( sur->asBinder() ).promote();
2739b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return result;
2740b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
27417303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
2742b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// ---------------------------------------------------------------------------
274396f0819f81293076e652792794a961543e6750d7Mathias Agopian
27449a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::GraphicBufferAlloc() {}
27459a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
27469a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::~GraphicBufferAlloc() {}
27479a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
27489a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h,
2749d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        PixelFormat format, uint32_t usage, status_t* error) {
27509a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(w, h, format, usage));
27519a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    status_t err = graphicBuffer->initCheck();
2752d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian    *error = err;
2753a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (err != 0 || graphicBuffer->handle == 0) {
2754d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        if (err == NO_MEMORY) {
2755d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian            GraphicBuffer::dumpAllocationsToSystemLog();
2756d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        }
2757e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE("GraphicBufferAlloc::createGraphicBuffer(w=%d, h=%d) "
2758a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian             "failed (%s), handle=%p",
2759a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                w, h, strerror(-err), graphicBuffer->handle);
27609a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis        return 0;
27619a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    }
27629a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    return graphicBuffer;
27639a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis}
27649a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
27659a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis// ---------------------------------------------------------------------------
27669a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
2767edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
2768