SurfaceFlinger.cpp revision a6b32db164e7834e211261046f3229bf50bc0098
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                    }
1165a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                    continue;
1166a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                }
1167a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                // render the layer
11681b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian                layer->draw(hw, clip);
11694b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian            }
1170a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall            if (cur != end) {
1171a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall                ++cur;
1172a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall            }
11734b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian        }
11744b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian    }
1175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
11771b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopianvoid SurfaceFlinger::debugFlashRegions(const DisplayHardware& hw)
1178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
11790a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    const uint32_t flags = hw.getFlags();
118053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian    const int32_t height = hw.getHeight();
11810656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian    if (mSwapRegion.isEmpty()) {
118253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian        return;
118353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian    }
11840a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
1185a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian    if (!(flags & DisplayHardware::SWAP_RECTANGLE)) {
11860a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        const Region repaint((flags & DisplayHardware::PARTIAL_UPDATES) ?
11870a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian                mDirtyRegion.bounds() : hw.bounds());
11881b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian        composeSurfaces(hw, repaint);
11890a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    }
11900a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
1191c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_EXTERNAL_OES);
1192c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_2D);
1193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_BLEND);
1194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
11950926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    static int toggle = 0;
11960926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    toggle = 1 - toggle;
11970926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    if (toggle) {
11980a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        glColor4f(1, 0, 1, 1);
11990926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    } else {
12000a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        glColor4f(1, 1, 0, 1);
12010926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    }
1202edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
120320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    Region::const_iterator it = mDirtyRegion.begin();
120420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    Region::const_iterator const end = mDirtyRegion.end();
120520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    while (it != end) {
120620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        const Rect& r = *it++;
1207edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLfloat vertices[][2] = {
120853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.left,  height - r.top },
120953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.left,  height - r.bottom },
121053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.right, height - r.bottom },
121153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.right, height - r.top }
1212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        };
1213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glVertexPointer(2, GL_FLOAT, 0, vertices);
1214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
12160a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
12170656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian    hw.flip(mSwapRegion);
1218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mDebugRegion > 1)
12200a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        usleep(mDebugRegion * 1000);
1221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::drawWormhole() const
1224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Region region(mWormholeRegion.intersect(mDirtyRegion));
1226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (region.isEmpty())
1227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1229f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    glDisable(GL_TEXTURE_EXTERNAL_OES);
1230b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian    glDisable(GL_TEXTURE_2D);
1231f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    glDisable(GL_BLEND);
1232b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian    glColor4f(0,0,0,0);
1233f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian
1234f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    GLfloat vertices[4][2];
1235f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    glVertexPointer(2, GL_FLOAT, 0, vertices);
1236f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    Region::const_iterator it = region.begin();
1237f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    Region::const_iterator const end = region.end();
1238f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    while (it != end) {
1239f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        const Rect& r = *it++;
1240f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[0][0] = r.left;
1241f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[0][1] = r.top;
1242f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[1][0] = r.right;
1243f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[1][1] = r.top;
1244f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[2][0] = r.right;
1245f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[2][1] = r.bottom;
1246f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[3][0] = r.left;
1247f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[3][1] = r.bottom;
1248f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1249f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    }
1250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1252076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::addLayer(const sp<LayerBase>& layer)
1253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
1255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    addLayer_l(layer);
1256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
1257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1259edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1260076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::addLayer_l(const sp<LayerBase>& layer)
1261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1262f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian    ssize_t i = mCurrentState.layersSortedByZ.add(layer);
12631b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    return (i < 0) ? status_t(i) : status_t(NO_ERROR);
12641b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian}
12651b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
126696f0819f81293076e652792794a961543e6750d7Mathias Agopianssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
126796f0819f81293076e652792794a961543e6750d7Mathias Agopian        const sp<LayerBaseClient>& lbc)
12681b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
126996f0819f81293076e652792794a961543e6750d7Mathias Agopian    // attach this layer to the client
12704f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    size_t name = client->attachLayer(lbc);
12714f113740180b6512b43723c4728f262882dc9b45Mathias Agopian
12724f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    Mutex::Autolock _l(mStateLock);
127396f0819f81293076e652792794a961543e6750d7Mathias Agopian
127496f0819f81293076e652792794a961543e6750d7Mathias Agopian    // add this layer to the current state list
127596f0819f81293076e652792794a961543e6750d7Mathias Agopian    addLayer_l(lbc);
127696f0819f81293076e652792794a961543e6750d7Mathias Agopian
12774f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    return ssize_t(name);
127896f0819f81293076e652792794a961543e6750d7Mathias Agopian}
127996f0819f81293076e652792794a961543e6750d7Mathias Agopian
128096f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer)
128196f0819f81293076e652792794a961543e6750d7Mathias Agopian{
128296f0819f81293076e652792794a961543e6750d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
128396f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = purgatorizeLayer_l(layer);
128496f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR)
128596f0819f81293076e652792794a961543e6750d7Mathias Agopian        setTransactionFlags(eTransactionNeeded);
128696f0819f81293076e652792794a961543e6750d7Mathias Agopian    return err;
1287edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1288edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1289076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase)
1290edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1291b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<LayerBaseClient> lbc(layerBase->getLayerBaseClient());
1292b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (lbc != 0) {
12930d1561275e80073807ac04728951782d943f8882Mathias Agopian        mLayerMap.removeItem( lbc->getSurfaceBinder() );
1294b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    }
1295edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase);
1296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (index >= 0) {
1297076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved = true;
1298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
1299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
13003d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    return status_t(index);
1301edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1302edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
13039a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase)
13049a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
130576cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    // First add the layer to the purgatory list, which makes sure it won't
130676cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    // go away, then remove it from the main list (through a transaction).
13079a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    ssize_t err = removeLayer_l(layerBase);
130876cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    if (err >= 0) {
130976cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian        mLayerPurgatory.add(layerBase);
131076cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    }
13118c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian
13122f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall    mLayersPendingRemoval.push(layerBase);
13130b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian
13143d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // it's possible that we don't find a layer, because it might
13153d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // have been destroyed already -- this is not technically an error
131696f0819f81293076e652792794a961543e6750d7Mathias Agopian    // from the user because there is a race between Client::destroySurface(),
131796f0819f81293076e652792794a961543e6750d7Mathias Agopian    // ~Client() and ~ISurface().
13189a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err;
13199a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
13209a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
132196f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::invalidateLayerVisibility(const sp<LayerBase>& layer)
1322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
132396f0819f81293076e652792794a961543e6750d7Mathias Agopian    layer->forceVisibilityTransaction();
132496f0819f81293076e652792794a961543e6750d7Mathias Agopian    setTransactionFlags(eTraversalNeeded);
132596f0819f81293076e652792794a961543e6750d7Mathias Agopian    return NO_ERROR;
1326edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1327edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1328dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopianuint32_t SurfaceFlinger::peekTransactionFlags(uint32_t flags)
1329dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian{
1330dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian    return android_atomic_release_load(&mTransactionFlags);
1331dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian}
1332dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian
1333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags)
1334edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1335edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return android_atomic_and(~flags, &mTransactionFlags) & flags;
1336edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1337edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1338bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags)
1339edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1340edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t old = android_atomic_or(flags, &mTransactionFlags);
1341edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((old & flags)==0) { // wake the server up
134299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        signalTransaction();
1343edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1344edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return old;
1345edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1346edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1347edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1348b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennisvoid SurfaceFlinger::setTransactionState(const Vector<ComposerState>& state,
134928378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        int orientation, uint32_t flags) {
1350698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
1351cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
135228378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    uint32_t transactionFlags = 0;
1353b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis    if (mCurrentState.orientation != orientation) {
1354b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis        if (uint32_t(orientation)<=eOrientation270 || orientation==42) {
1355b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis            mCurrentState.orientation = orientation;
135628378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis            transactionFlags |= eTransactionNeeded;
1357b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis        } else if (orientation != eOrientationUnchanged) {
135832397c1cd3327905173b36baa6fd1c579bc328ffSteve Block            ALOGW("setTransactionState: ignoring unrecognized orientation: %d",
1359b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis                    orientation);
1360b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis        }
1361b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis    }
1362b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis
1363698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    const size_t count = state.size();
1364698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
1365698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const ComposerState& s(state[i]);
1366698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        sp<Client> client( static_cast<Client *>(s.client.get()) );
136728378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        transactionFlags |= setClientStateLocked(client, s.state);
1368698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    }
1369386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian
137028378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    if (transactionFlags) {
1371386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // this triggers the transaction
137228378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        setTransactionFlags(transactionFlags);
1373698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian
1374386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // if this is a synchronous transaction, wait for it to take effect
1375386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // before returning.
1376386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        if (flags & eSynchronous) {
1377386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            mTransationPending = true;
1378386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        }
1379386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        while (mTransationPending) {
1380386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
1381386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            if (CC_UNLIKELY(err != NO_ERROR)) {
1382386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                // just in case something goes wrong in SF, return to the
1383386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                // called after a few seconds.
138432397c1cd3327905173b36baa6fd1c579bc328ffSteve Block                ALOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!");
1385386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                mTransationPending = false;
1386386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                break;
1387386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            }
1388cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        }
1389edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1390edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1391edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
13920ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopiansp<ISurface> SurfaceFlinger::createSurface(
13930ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        ISurfaceComposerClient::surface_data_t* params,
13940ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const String8& name,
13950ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const sp<Client>& client,
1396edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        DisplayID d, uint32_t w, uint32_t h, PixelFormat format,
1397edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t flags)
1398edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1399076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBaseClient> layer;
1400a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    sp<ISurface> surfaceHandle;
14016e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian
14026e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    if (int32_t(w|h) < 0) {
1403e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE("createSurface() failed, w or h is negative (w=%d, h=%d)",
14046e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian                int(w), int(h));
14056e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian        return surfaceHandle;
14066e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    }
14078b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
1408ff615cc7a1cceedd705b0623b058c54669b29596Mathias Agopian    //ALOGD("createSurface for (%d x %d), name=%s", w, h, name.string());
1409b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<Layer> normalLayer;
1410edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (flags & eFXSurfaceMask) {
1411edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceNormal:
1412a5529c8778c2f407f482fc12165aeb76c0f505c2Mathias Agopian            normalLayer = createNormalSurface(client, d, w, h, flags, format);
1413a5529c8778c2f407f482fc12165aeb76c0f505c2Mathias Agopian            layer = normalLayer;
1414edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
1415edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceBlur:
14161293a8eb567fd63c072a6970fa9dcf37d076059fMathias Agopian            // for now we treat Blur as Dim, until we can implement it
14171293a8eb567fd63c072a6970fa9dcf37d076059fMathias Agopian            // efficiently.
1418edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceDim:
141996f0819f81293076e652792794a961543e6750d7Mathias Agopian            layer = createDimSurface(client, d, w, h, flags);
1420edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
1421118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        case eFXSurfaceScreenshot:
1422118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian            layer = createScreenshotSurface(client, d, w, h, flags);
1423118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian            break;
1424edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1425edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1426076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (layer != 0) {
142796f0819f81293076e652792794a961543e6750d7Mathias Agopian        layer->initStates(w, h, flags);
1428285dbde2e0cd0057be070ded3be8f5f453147edcMathias Agopian        layer->setName(name);
142996f0819f81293076e652792794a961543e6750d7Mathias Agopian        ssize_t token = addClientLayer(client, layer);
1430b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1431edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        surfaceHandle = layer->getSurface();
14328b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber        if (surfaceHandle != 0) {
143396f0819f81293076e652792794a961543e6750d7Mathias Agopian            params->token = token;
1434a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            params->identity = layer->getIdentity();
1435b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            if (normalLayer != 0) {
1436b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian                Mutex::Autolock _l(mStateLock);
1437a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                mLayerMap.add(layer->getSurfaceBinder(), normalLayer);
1438b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            }
14391c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        }
1440b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
144196f0819f81293076e652792794a961543e6750d7Mathias Agopian        setTransactionFlags(eTransactionNeeded);
1442edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1443edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1444edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return surfaceHandle;
1445edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1446edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1447b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<Layer> SurfaceFlinger::createNormalSurface(
1448f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        const sp<Client>& client, DisplayID display,
144996f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags,
14501c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        PixelFormat& format)
1451edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1452edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize the surfaces
1453edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (format) { // TODO: take h/w into account
1454edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSPARENT:
1455edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSLUCENT:
1456edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        format = PIXEL_FORMAT_RGBA_8888;
1457edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1458edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_OPAQUE:
1459a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888
1460a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian        format = PIXEL_FORMAT_RGB_565;
1461a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#else
14628f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian        format = PIXEL_FORMAT_RGBX_8888;
1463a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif
1464edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1465edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1466edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1467a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888
1468a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian    if (format == PIXEL_FORMAT_RGBX_8888)
1469a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian        format = PIXEL_FORMAT_RGBA_8888;
1470a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif
1471a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian
147296f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<Layer> layer = new Layer(this, display, client);
1473f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian    status_t err = layer->setBuffers(w, h, format, flags);
147499ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten    if (CC_LIKELY(err != NO_ERROR)) {
1475e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE("createNormalSurfaceLocked() failed (%s)", strerror(-err));
1476076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        layer.clear();
1477edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1478edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1479edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1480edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1481b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<LayerDim> SurfaceFlinger::createDimSurface(
1482f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        const sp<Client>& client, DisplayID display,
148396f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags)
1484edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
148596f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<LayerDim> layer = new LayerDim(this, display, client);
1486118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    return layer;
1487118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
1488118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
1489118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopiansp<LayerScreenshot> SurfaceFlinger::createScreenshotSurface(
1490118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        const sp<Client>& client, DisplayID display,
1491118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags)
1492118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{
1493118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    sp<LayerScreenshot> layer = new LayerScreenshot(this, display, client);
1494edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1495edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1496edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
149796f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeSurface(const sp<Client>& client, SurfaceID sid)
14989a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
14999a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    /*
15009a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     * called by the window manager, when a surface should be marked for
15019a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     * destruction.
15028b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber     *
15030aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * The surface is removed from the current and drawing lists, but placed
15040aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * in the purgatory queue, so it's not destroyed right-away (we need
15050aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * to wait for all client's references to go away first).
15069a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     */
15079a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
150848d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    status_t err = NAME_NOT_FOUND;
15090aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian    Mutex::Autolock _l(mStateLock);
151096f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<LayerBaseClient> layer = client->getLayerUser(sid);
1511b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam
151248d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    if (layer != 0) {
151348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        err = purgatorizeLayer_l(layer);
151448d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        if (err == NO_ERROR) {
151548d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian            setTransactionFlags(eTransactionNeeded);
151648d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        }
15179a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    }
15189a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return err;
15199a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
15209a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
1521ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopianstatus_t SurfaceFlinger::destroySurface(const wp<LayerBaseClient>& layer)
1522edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1523759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian    // called by ~ISurface() when all references are gone
1524ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    status_t err = NO_ERROR;
1525ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    sp<LayerBaseClient> l(layer.promote());
1526ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    if (l != NULL) {
1527ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        Mutex::Autolock _l(mStateLock);
1528ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        err = removeLayer_l(l);
1529ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        if (err == NAME_NOT_FOUND) {
1530ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // The surface wasn't in the current list, which means it was
1531ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // removed already, which means it is in the purgatory,
1532ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // and need to be removed from there.
1533ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            ssize_t idx = mLayerPurgatory.remove(l);
1534e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block            ALOGE_IF(idx < 0,
1535ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian                    "layer=%p is not in the purgatory list", l.get());
1536f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        }
1537e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE_IF(err<0 && err != NAME_NOT_FOUND,
1538ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian                "error removing layer=%p (%s)", l.get(), strerror(-err));
1539ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    }
1540ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    return err;
1541edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1542edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1543698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopianuint32_t SurfaceFlinger::setClientStateLocked(
154496f0819f81293076e652792794a961543e6750d7Mathias Agopian        const sp<Client>& client,
1545698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const layer_state_t& s)
1546edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1547edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t flags = 0;
1548698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    sp<LayerBaseClient> layer(client->getLayerUser(s.surface));
1549698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    if (layer != 0) {
1550698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const uint32_t what = s.what;
1551698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & ePositionChanged) {
1552698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setPosition(s.x, s.y))
1553698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1554698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1555698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eLayerChanged) {
1556698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
1557698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setLayer(s.z)) {
1558698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                mCurrentState.layersSortedByZ.removeAt(idx);
1559698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                mCurrentState.layersSortedByZ.add(layer);
1560698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                // we need traversal (state changed)
1561698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                // AND transaction (list changed)
1562698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTransactionNeeded|eTraversalNeeded;
1563edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1564698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1565698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eSizeChanged) {
1566698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setSize(s.w, s.h)) {
1567698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1568edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1569edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1570698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eAlphaChanged) {
1571698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f)))
1572698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1573698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1574698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eMatrixChanged) {
1575698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setMatrix(s.matrix))
1576698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1577698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1578698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eTransparentRegionChanged) {
1579698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setTransparentRegionHint(s.transparentRegion))
1580698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1581698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1582698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eVisibilityChanged) {
1583698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setFlags(s.flags, s.mask))
1584698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1585698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1586f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        if (what & eCropChanged) {
1587f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis            if (layer->setCrop(s.crop))
1588f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis                flags |= eTraversalNeeded;
1589f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        }
1590edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1591698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    return flags;
1592edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1593edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1594b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// ---------------------------------------------------------------------------
1595b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
1596b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopianvoid SurfaceFlinger::onScreenAcquired() {
15978e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross    ALOGD("Screen about to return, flinger = %p", this);
15981b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    const DisplayHardware& hw(getDefaultDisplayHardware()); // XXX: this should be per DisplayHardware
1599b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    hw.acquireScreen();
160022ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian    mEventThread->onScreenAcquired();
1601b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    // this is a temporary work-around, eventually this should be called
1602b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    // by the power-manager
1603b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    SurfaceFlinger::turnElectronBeamOn(mElectronBeamAnimationMode);
160422ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian    // from this point on, SF will process updates again
16058acce2046ac7086c3dcfb1fc7c9c39f31de48694Mathias Agopian    repaintEverything();
1606edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1607edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1608b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopianvoid SurfaceFlinger::onScreenReleased() {
16098e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross    ALOGD("About to give-up screen, flinger = %p", this);
16101b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    const DisplayHardware& hw(getDefaultDisplayHardware()); // XXX: this should be per DisplayHardware
1611b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    if (hw.isScreenAcquired()) {
161222ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian        mEventThread->onScreenReleased();
1613b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        hw.releaseScreen();
1614b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        // from this point on, SF will stop drawing
1615b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    }
1616b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian}
1617b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
16188e533069e5721e55cb9768e140e16546c3a4a8b6Colin Crossvoid SurfaceFlinger::unblank() {
1619b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    class MessageScreenAcquired : public MessageBase {
1620b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        SurfaceFlinger* flinger;
1621b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    public:
1622b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        MessageScreenAcquired(SurfaceFlinger* flinger) : flinger(flinger) { }
1623b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        virtual bool handler() {
1624b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            flinger->onScreenAcquired();
1625b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            return true;
1626b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        }
1627b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    };
1628b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    sp<MessageBase> msg = new MessageScreenAcquired(this);
1629b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    postMessageSync(msg);
1630edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1631edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
16328e533069e5721e55cb9768e140e16546c3a4a8b6Colin Crossvoid SurfaceFlinger::blank() {
1633b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    class MessageScreenReleased : public MessageBase {
1634b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        SurfaceFlinger* flinger;
1635b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    public:
1636b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        MessageScreenReleased(SurfaceFlinger* flinger) : flinger(flinger) { }
1637b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        virtual bool handler() {
1638b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            flinger->onScreenReleased();
1639b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            return true;
1640b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        }
1641b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    };
1642b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    sp<MessageBase> msg = new MessageScreenReleased(this);
1643b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    postMessageSync(msg);
1644b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian}
1645b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
1646b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// ---------------------------------------------------------------------------
1647b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
1648edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
1649edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
16501d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling    const size_t SIZE = 4096;
1651edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char buffer[SIZE];
1652edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    String8 result;
165399b49840d309727678b77403d6cc9f920111623fMathias Agopian
165499b49840d309727678b77403d6cc9f920111623fMathias Agopian    if (!PermissionCache::checkCallingPermission(sDump)) {
1655edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        snprintf(buffer, SIZE, "Permission Denial: "
1656edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                "can't dump SurfaceFlinger from pid=%d, uid=%d\n",
1657edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                IPCThreadState::self()->getCallingPid(),
1658edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                IPCThreadState::self()->getCallingUid());
1659edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        result.append(buffer);
1660edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
16619795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // Try to get the main lock, but don't insist if we can't
16629795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // (this would indicate SF is stuck, but we want to be able to
16639795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // print something in dumpsys).
16649795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        int retry = 3;
16659795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        while (mStateLock.tryLock()<0 && --retry>=0) {
16669795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            usleep(1000000);
16679795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
16689795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const bool locked(retry >= 0);
16699795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (!locked) {
16708b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber            snprintf(buffer, SIZE,
16719795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "SurfaceFlinger appears to be unresponsive, "
16729795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "dumping anyways (no locks held)\n");
16739795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            result.append(buffer);
16749795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
16759795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
167682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        bool dumpAll = true;
167782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        size_t index = 0;
167825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        size_t numArgs = args.size();
167925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        if (numArgs) {
168025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
168125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--list"))) {
168225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                index++;
168325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                listLayersLocked(args, index, result, buffer, SIZE);
168435aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
168525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            }
168625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
168725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
168825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--latency"))) {
168982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                index++;
169082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                dumpStatsLocked(args, index, result, buffer, SIZE);
169135aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
169282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            }
169325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
169425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
169525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--latency-clear"))) {
169625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                index++;
169725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                clearStatsLocked(args, index, result, buffer, SIZE);
169835aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
169925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            }
1700edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
17011b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
170282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (dumpAll) {
170382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            dumpAllLocked(result, buffer, SIZE);
170482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
170548b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
170682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (locked) {
170782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mStateLock.unlock();
170848b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        }
170982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
171082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    write(fd, result.string(), result.size());
171182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    return NO_ERROR;
171282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
171348b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
171425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::listLayersLocked(const Vector<String16>& args, size_t& index,
171525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        String8& result, char* buffer, size_t SIZE) const
171625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
171725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
171825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const size_t count = currentLayers.size();
171925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
172025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
172125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        snprintf(buffer, SIZE, "%s\n", layer->getName().string());
172225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        result.append(buffer);
172325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
172425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
172525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
172682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index,
172782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        String8& result, char* buffer, size_t SIZE) const
172882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
172982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    String8 name;
173082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    if (index < args.size()) {
173182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        name = String8(args[index]);
173282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        index++;
173382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
173448b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
173582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
173682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const size_t count = currentLayers.size();
173782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    for (size_t i=0 ; i<count ; i++) {
173882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
173982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (name.isEmpty()) {
174082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            snprintf(buffer, SIZE, "%s\n", layer->getName().string());
174182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            result.append(buffer);
174282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
174382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (name.isEmpty() || (name == layer->getName())) {
174482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            layer->dumpStats(result, buffer, SIZE);
174582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
174682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
174782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
1748ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian
174925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& index,
175025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        String8& result, char* buffer, size_t SIZE) const
175125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
175225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    String8 name;
175325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    if (index < args.size()) {
175425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        name = String8(args[index]);
175525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        index++;
175625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
175725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
175825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
175925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const size_t count = currentLayers.size();
176025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
176125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
176225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        if (name.isEmpty() || (name == layer->getName())) {
176325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            layer->clearStats();
176425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        }
176525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
176625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
176725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
176882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpAllLocked(
176982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        String8& result, char* buffer, size_t SIZE) const
177082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
177182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    // figure out if we're stuck somewhere
177282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t now = systemTime();
177382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t inSwapBuffers(mDebugInSwapBuffers);
177482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t inTransaction(mDebugInTransaction);
177582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0;
177682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0;
1777bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
177882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
177982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump the visible layer list
178082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
178182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
178282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const size_t count = currentLayers.size();
178382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "Visible layers (count = %d)\n", count);
178482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
178582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    for (size_t i=0 ; i<count ; i++) {
178682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
178782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        layer->dump(result, buffer, SIZE);
178882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
1789bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
179082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
179182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump the layers in the purgatory
179282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
1793ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian
179482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const size_t purgatorySize = mLayerPurgatory.size();
179582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "Purgatory state (%d entries)\n", purgatorySize);
179682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
179782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    for (size_t i=0 ; i<purgatorySize ; i++) {
179882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
179982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        layer->shortDump(result, buffer, SIZE);
180082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
18011b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
180282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
180382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump SurfaceFlinger global state
180482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
18051b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
180682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "SurfaceFlinger global state:\n");
180782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
18081b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
18091b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    const DisplayHardware& hw(getDefaultDisplayHardware());
181082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const GLExtensions& extensions(GLExtensions::getInstance());
181182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "GLES: %s, %s, %s\n",
181282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            extensions.getVendor(),
181382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            extensions.getRenderer(),
181482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            extensions.getVersion());
181582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
1816d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
181782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "EGL : %s\n",
18181b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian            eglQueryString(hw.getEGLDisplay(),
181982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                    EGL_VERSION_HW_ANDROID));
182082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
182173d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian
182282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "EXTS: %s\n", extensions.getExtension());
182382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
18249795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
182582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    mWormholeRegion.dump(result, "WormholeRegion");
182682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE,
182782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  orientation=%d, canDraw=%d\n",
182882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mCurrentState.orientation, hw.canDraw());
182982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
183082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE,
183182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  last eglSwapBuffers() time: %f us\n"
183282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  last transaction time     : %f us\n"
1833c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian            "  transaction-flags         : %08x\n"
183482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  refresh-rate              : %f fps\n"
183582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  x-dpi                     : %f\n"
1836b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian            "  y-dpi                     : %f\n"
1837b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian            "  density                   : %f\n",
183882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mLastSwapBufferTime/1000.0,
183982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mLastTransactionTime/1000.0,
1840c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian            mTransactionFlags,
184182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            hw.getRefreshRate(),
184282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            hw.getDpiX(),
1843b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian            hw.getDpiY(),
1844b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian            hw.getDensity());
184582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
184682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
184782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "  eglSwapBuffers time: %f us\n",
184882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            inSwapBuffersDuration/1000.0);
184982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
185082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
185182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "  transaction time: %f us\n",
185282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            inTransactionDuration/1000.0);
185382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
185482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
185582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
185682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * VSYNC state
185782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
185882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    mEventThread->dump(result, buffer, SIZE);
185982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
186082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
186182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump HWComposer state
186282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
186382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    HWComposer& hwc(hw.getHwComposer());
186482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "h/w composer state:\n");
186582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
186682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "  h/w composer %s and %s\n",
186782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            hwc.initCheck()==NO_ERROR ? "present" : "not present",
186882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                    (mDebugDisableHWC || mDebugRegion) ? "disabled" : "enabled");
186982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
18703b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    hwc.dump(result, buffer, SIZE, hw.getVisibleLayersSortedByZ());
187182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
187282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
187382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump gralloc state
187482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
187582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
187682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    alloc.dump(result);
187782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    hw.dump(result);
1878edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1879edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1880edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::onTransact(
1881edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
1882edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1883edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (code) {
1884edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case CREATE_CONNECTION:
1885698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        case SET_TRANSACTION_STATE:
1886edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case SET_ORIENTATION:
1887edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case BOOT_FINISHED:
188859119e658a12279e8fff508f8773843de2d90917Mathias Agopian        case TURN_ELECTRON_BEAM_OFF:
18899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        case TURN_ELECTRON_BEAM_ON:
18908e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross        case BLANK:
18918e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross        case UNBLANK:
1892edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        {
1893edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // codes that require permission check
1894edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            IPCThreadState* ipc = IPCThreadState::self();
1895edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int pid = ipc->getCallingPid();
1896a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian            const int uid = ipc->getCallingUid();
189799b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
189899b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) {
1899e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block                ALOGE("Permission Denial: "
1900375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                        "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
1901375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                return PERMISSION_DENIED;
1902edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
19031b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
19041b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
19051b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        case CAPTURE_SCREEN:
19061b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
19071b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            // codes that require permission check
19081b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
19091b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int pid = ipc->getCallingPid();
19101b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int uid = ipc->getCallingUid();
191199b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
191299b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) {
1913e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block                ALOGE("Permission Denial: "
19141b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                        "can't read framebuffer pid=%d, uid=%d", pid, uid);
19151b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                return PERMISSION_DENIED;
19161b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            }
19171b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
1918edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1919edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
19201b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
1921edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
1922edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
1923b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        CHECK_INTERFACE(ISurfaceComposer, data, reply);
192499ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten        if (CC_UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) {
1925375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
1926375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int pid = ipc->getCallingPid();
1927375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int uid = ipc->getCallingUid();
1928e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block            ALOGE("Permission Denial: "
1929375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                    "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
1930edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return PERMISSION_DENIED;
1931edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1932edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int n;
1933edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        switch (code) {
193401b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian            case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE
193535b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian            case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE
1936edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1937edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1002:  // SHOW_UPDATES
1938edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                n = data.readInt32();
1939edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDebugRegion = n ? n : (mDebugRegion ? 0 : 1);
194053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
194153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
1942edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1943edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1004:{ // repaint everything
194453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
1945cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
1946cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            }
1947cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            case 1005:{ // force transaction
1948cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
1949cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
1950edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
19514d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            case 1006:{ // send empty update
19524d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian                signalRefresh();
19534d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian                return NO_ERROR;
19544d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            }
195553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian            case 1008:  // toggle use of hw composer
195653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                n = data.readInt32();
195753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                mDebugDisableHWC = n ? 1 : 0;
195853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
195953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
196053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                return NO_ERROR;
1961a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian            case 1009:  // toggle use of transform hint
1962a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                n = data.readInt32();
1963a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                mDebugDisableTransformHint = n ? 1 : 0;
1964a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                invalidateHwcGeometry();
1965a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                repaintEverything();
1966a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                return NO_ERROR;
1967edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1010:  // interrogate.
196801b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian                reply->writeInt32(0);
1969edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(0);
1970edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(mDebugRegion);
1971b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                reply->writeInt32(0);
197212839bee29bdcc65731b4d42029cc59e2320c5c4Dianne Hackborn                reply->writeInt32(mDebugDisableHWC);
1973edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1974edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1013: {
1975edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                Mutex::Autolock _l(mStateLock);
19761b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian                const DisplayHardware& hw(getDefaultDisplayHardware());
1977edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(hw.getPageFlipCount());
1978edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1979edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return NO_ERROR;
1980edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1981edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1982edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return err;
1983edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1984edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
198553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopianvoid SurfaceFlinger::repaintEverything() {
19861b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    const DisplayHardware& hw(getDefaultDisplayHardware()); // FIXME: this cannot be bound the default display
19870dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    const Rect bounds(hw.getBounds());
19880dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    setInvalidateRegion(Region(bounds));
198999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    signalTransaction();
199053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian}
199153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian
19920dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopianvoid SurfaceFlinger::setInvalidateRegion(const Region& reg) {
19930dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    Mutex::Autolock _l(mInvalidateLock);
19940dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    mInvalidateRegion = reg;
19950dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian}
19960dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian
19970dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias AgopianRegion SurfaceFlinger::getAndClearInvalidateRegion() {
19980dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    Mutex::Autolock _l(mInvalidateLock);
19990dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    Region reg(mInvalidateRegion);
20000dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    mInvalidateRegion.clear();
20010dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    return reg;
20020dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian}
20030dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian
200459119e658a12279e8fff508f8773843de2d90917Mathias Agopian// ---------------------------------------------------------------------------
200559119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2006118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopianstatus_t SurfaceFlinger::renderScreenToTexture(DisplayID dpy,
2007118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        GLuint* textureName, GLfloat* uOut, GLfloat* vOut)
2008118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{
2009118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    Mutex::Autolock _l(mStateLock);
2010118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    return renderScreenToTextureLocked(dpy, textureName, uOut, vOut);
2011118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
2012118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
20139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::renderScreenToTextureLocked(DisplayID dpy,
20149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        GLuint* textureName, GLfloat* uOut, GLfloat* vOut)
201559119e658a12279e8fff508f8773843de2d90917Mathias Agopian{
201622ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian    ATRACE_CALL();
201722ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian
201859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
201959119e658a12279e8fff508f8773843de2d90917Mathias Agopian        return INVALID_OPERATION;
202059119e658a12279e8fff508f8773843de2d90917Mathias Agopian
202159119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // get screen geometry
20221b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    const DisplayHardware& hw(getDisplayHardware(dpy));
202359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    const uint32_t hw_w = hw.getWidth();
202459119e658a12279e8fff508f8773843de2d90917Mathias Agopian    const uint32_t hw_h = hw.getHeight();
202559119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLfloat u = 1;
202659119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLfloat v = 1;
202759119e658a12279e8fff508f8773843de2d90917Mathias Agopian
202859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // make sure to clear all GL error flags
202959119e658a12279e8fff508f8773843de2d90917Mathias Agopian    while ( glGetError() != GL_NO_ERROR ) ;
203059119e658a12279e8fff508f8773843de2d90917Mathias Agopian
203159119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // create a FBO
203259119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLuint name, tname;
203359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glGenTextures(1, &tname);
203459119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
2035a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2036a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
20379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
20389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            hw_w, hw_h, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
203959119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (glGetError() != GL_NO_ERROR) {
2040015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian        while ( glGetError() != GL_NO_ERROR ) ;
204159119e658a12279e8fff508f8773843de2d90917Mathias Agopian        GLint tw = (2 << (31 - clz(hw_w)));
204259119e658a12279e8fff508f8773843de2d90917Mathias Agopian        GLint th = (2 << (31 - clz(hw_h)));
20439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
20449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian                tw, th, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
204559119e658a12279e8fff508f8773843de2d90917Mathias Agopian        u = GLfloat(hw_w) / tw;
204659119e658a12279e8fff508f8773843de2d90917Mathias Agopian        v = GLfloat(hw_h) / th;
204759119e658a12279e8fff508f8773843de2d90917Mathias Agopian    }
204859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glGenFramebuffersOES(1, &name);
204959119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
20509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES,
20519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0);
205259119e658a12279e8fff508f8773843de2d90917Mathias Agopian
20539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // redraw the screen entirely...
2054c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_EXTERNAL_OES);
2055c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_2D);
20569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glClearColor(0,0,0,1);
20579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glClear(GL_COLOR_BUFFER_BIT);
2058a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glMatrixMode(GL_MODELVIEW);
2059a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glLoadIdentity();
20603b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    const Vector< sp<LayerBase> >& layers(hw.getVisibleLayersSortedByZ());
20619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const size_t count = layers.size();
20629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (size_t i=0 ; i<count ; ++i) {
20639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
20641b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian        layer->drawForSreenShot(hw);
20659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
206659119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2067118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    hw.compositionComplete();
2068118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
20699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // back to main framebuffer
20709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
20719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDeleteFramebuffersOES(1, &name);
207259119e658a12279e8fff508f8773843de2d90917Mathias Agopian
20739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *textureName = tname;
20749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *uOut = u;
20759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *vOut = v;
20769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
20779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
207859119e658a12279e8fff508f8773843de2d90917Mathias Agopian
20799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// ---------------------------------------------------------------------------
208059119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2081ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopianclass VSyncWaiter {
2082ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    DisplayEventReceiver::Event buffer[4];
2083ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    sp<Looper> looper;
2084ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    sp<IDisplayEventConnection> events;
2085ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    sp<BitTube> eventTube;
2086ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopianpublic:
2087ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    VSyncWaiter(const sp<EventThread>& eventThread) {
2088ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        looper = new Looper(true);
2089ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        events = eventThread->createEventConnection();
2090ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        eventTube = events->getDataChannel();
2091ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        looper->addFd(eventTube->getFd(), 0, ALOOPER_EVENT_INPUT, 0, 0);
2092ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        events->requestNextVsync();
2093ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    }
2094ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
2095ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    void wait() {
2096ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        ssize_t n;
2097ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
2098ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        looper->pollOnce(-1);
2099ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        // we don't handle any errors here, it doesn't matter
2100ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        // and we don't want to take the risk to get stuck.
2101ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
2102ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        // drain the events...
2103ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        while ((n = DisplayEventReceiver::getEvents(
2104ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian                eventTube, buffer, 4)) > 0) ;
2105ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
2106ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        events->requestNextVsync();
2107ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    }
2108ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian};
2109ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
21109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::electronBeamOffAnimationImplLocked()
21119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
21129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // get screen geometry
21131b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    const DisplayHardware& hw(getDefaultDisplayHardware());
21149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_w = hw.getWidth();
21159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_h = hw.getHeight();
2116a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    const Region screenBounds(hw.getBounds());
211759119e658a12279e8fff508f8773843de2d90917Mathias Agopian
21189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat u, v;
21199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLuint tname;
2120118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    status_t result = renderScreenToTextureLocked(0, &tname, &u, &v);
21219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (result != NO_ERROR) {
21229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return result;
21239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
212459119e658a12279e8fff508f8773843de2d90917Mathias Agopian
21259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat vtx[8];
2126a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    const GLfloat texCoords[4][2] = { {0,0}, {0,v}, {u,v}, {u,0} };
21279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
21289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
21299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
21309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2131b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2132b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
21339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
21349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
21359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glVertexPointer(2, GL_FLOAT, 0, vtx);
21369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2137ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    /*
2138ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     * Texture coordinate mapping
2139ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *
2140ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *                 u
2141ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *    1 +----------+---+
2142ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |     |    |   |  image is inverted
2143ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |     V    |   |  w.r.t. the texture
2144ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *  1-v +----------+   |  coordinates
2145ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |              |
2146ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |              |
2147ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |              |
2148ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *    0 +--------------+
2149ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      0              1
2150ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *
2151ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     */
2152ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian
21539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class s_curve_interpolator {
21549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float nbFrames, s, v;
21559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
21569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        s_curve_interpolator(int nbFrames, float s)
21579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : nbFrames(1.0f / (nbFrames-1)), s(s),
21589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian          v(1.0f + expf(-s + 0.5f*s)) {
21599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
21609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float operator()(int f) {
21619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const float x = f * nbFrames;
21629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f;
21639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
21649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
21659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class v_stretch {
21679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
21689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
21699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        v_stretch(uint32_t hw_w, uint32_t hw_h)
21709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
21719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
21729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
21739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w + (hw_w * v);
21749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = hw_h - (hw_h * v);
21759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
21769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
2177ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[0] = x;         vtx[1] = y;
2178ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
2179ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
2180ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
21819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
21829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
21839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class h_stretch {
21859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
21869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
21879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        h_stretch(uint32_t hw_w, uint32_t hw_h)
21889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
218959119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
21909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
21919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w - (hw_w * v);
21929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = 1.0f;
21939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
21949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
2195ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[0] = x;         vtx[1] = y;
2196ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
2197ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
2198ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
21999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
22009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
22019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2202ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    VSyncWaiter vsync(mEventThread);
2203ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
22049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // the full animation is 24 frames
2205ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    char value[PROPERTY_VALUE_MAX];
2206ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    property_get("debug.sf.electron_frames", value, "24");
2207ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    int nbFrames = (atoi(value) + 1) >> 1;
2208ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    if (nbFrames <= 0) // just in case
2209ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian        nbFrames = 24;
2210ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian
22119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itr(nbFrames, 7.5f);
22129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itg(nbFrames, 8.0f);
22139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itb(nbFrames, 8.5f);
22149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    v_stretch vverts(hw_w, hw_h);
2216a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian
2217a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glMatrixMode(GL_TEXTURE);
2218a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glLoadIdentity();
2219a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glMatrixMode(GL_MODELVIEW);
2220a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glLoadIdentity();
2221a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian
22229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnable(GL_BLEND);
22239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBlendFunc(GL_ONE, GL_ONE);
22249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=0 ; i<nbFrames ; i++) {
22259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float x, y, w, h;
22269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vr = itr(i);
22279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vg = itg(i);
22289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vb = itb(i);
22299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2230ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        // wait for vsync
2231ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        vsync.wait();
2232ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
22339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // clear screen
22349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(1,1,1,1);
22359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
22369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glEnable(GL_TEXTURE_2D);
223759119e658a12279e8fff508f8773843de2d90917Mathias Agopian
22389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the red plane
22399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vr);
22409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(1,0,0,1);
22419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
22429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the green plane
22449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vg);
22459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,1,0,1);
22469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
22479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the blue plane
22499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vb);
22509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,0,1,1);
22519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
22529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the white highlight (we use the last vertices)
225459119e658a12279e8fff508f8773843de2d90917Mathias Agopian        glDisable(GL_TEXTURE_2D);
225559119e658a12279e8fff508f8773843de2d90917Mathias Agopian        glColorMask(1,1,1,1);
22569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColor4f(vg, vg, vg, 1);
22579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
22589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
22599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
22609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    h_stretch hverts(hw_w, hw_h);
22629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_BLEND);
22639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_TEXTURE_2D);
22649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
22659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=0 ; i<nbFrames ; i++) {
22669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float v = itg(i);
22679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hverts(vtx, v);
2268ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
2269ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        // wait for vsync
2270ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        vsync.wait();
2271ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
22729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
22739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColor4f(1-v, 1-v, 1-v, 1);
22749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
22759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
22769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
22779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
22799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
22809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDeleteTextures(1, &tname);
2281a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    glDisable(GL_TEXTURE_2D);
2282c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_BLEND);
22839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
22849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
22859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::electronBeamOnAnimationImplLocked()
22879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
22889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    status_t result = PERMISSION_DENIED;
22899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
22919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return INVALID_OPERATION;
22929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // get screen geometry
22951b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    const DisplayHardware& hw(getDefaultDisplayHardware());
22969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_w = hw.getWidth();
22979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_h = hw.getHeight();
22989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const Region screenBounds(hw.bounds());
22999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
23009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat u, v;
23019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLuint tname;
23029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    result = renderScreenToTextureLocked(0, &tname, &u, &v);
23039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (result != NO_ERROR) {
23049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return result;
23059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
23069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
23079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat vtx[8];
23089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const GLfloat texCoords[4][2] = { {0,v}, {0,0}, {u,0}, {u,v} };
23099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
23109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
23119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
23129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2313b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2314b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
23159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
23169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
23179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glVertexPointer(2, GL_FLOAT, 0, vtx);
23189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
23199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class s_curve_interpolator {
23209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float nbFrames, s, v;
23219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
23229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        s_curve_interpolator(int nbFrames, float s)
23239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : nbFrames(1.0f / (nbFrames-1)), s(s),
23249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian          v(1.0f + expf(-s + 0.5f*s)) {
23259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
23269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float operator()(int f) {
23279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const float x = f * nbFrames;
23289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f;
23299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
23309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
23319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
23329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class v_stretch {
23339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
23349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
23359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        v_stretch(uint32_t hw_w, uint32_t hw_h)
23369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
233759119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
23389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
23399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w + (hw_w * v);
23409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = hw_h - (hw_h * v);
23419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
23429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
23439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[0] = x;         vtx[1] = y;
23449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
23459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
23469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
23479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
23489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
23499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
23509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class h_stretch {
23519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
23529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
23539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        h_stretch(uint32_t hw_w, uint32_t hw_h)
23549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
23559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
23569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
23579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w - (hw_w * v);
23589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = 1.0f;
23599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
23609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
23619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[0] = x;         vtx[1] = y;
23629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
23639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
23649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
23659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
23669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
23679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2368ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    VSyncWaiter vsync(mEventThread);
2369ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
2370a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian    // the full animation is 12 frames
2371a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian    int nbFrames = 8;
23729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itr(nbFrames, 7.5f);
23739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itg(nbFrames, 8.0f);
23749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itb(nbFrames, 8.5f);
23759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
23769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    h_stretch hverts(hw_w, hw_h);
23779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_BLEND);
23789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_TEXTURE_2D);
23799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
23809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=nbFrames-1 ; i>=0 ; i--) {
23819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float v = itg(i);
23829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hverts(vtx, v);
2383ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
2384ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        // wait for vsync
2385ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        vsync.wait();
2386ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
23879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
23889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColor4f(1-v, 1-v, 1-v, 1);
23899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
23909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
23919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
23929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2393a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian    nbFrames = 4;
23949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    v_stretch vverts(hw_w, hw_h);
23959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnable(GL_BLEND);
23969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBlendFunc(GL_ONE, GL_ONE);
23979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=nbFrames-1 ; i>=0 ; i--) {
23989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float x, y, w, h;
23999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vr = itr(i);
24009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vg = itg(i);
24019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vb = itb(i);
240259119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2403ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        // wait for vsync
2404ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        vsync.wait();
2405ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
24069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // clear screen
240759119e658a12279e8fff508f8773843de2d90917Mathias Agopian        glColorMask(1,1,1,1);
24089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
24099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glEnable(GL_TEXTURE_2D);
24109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
24119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the red plane
24129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vr);
24139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(1,0,0,1);
24149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
24159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
24169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the green plane
24179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vg);
24189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,1,0,1);
24199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
24209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
24219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the blue plane
24229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vb);
24239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,0,1,1);
24249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
24259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
24269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
242759119e658a12279e8fff508f8773843de2d90917Mathias Agopian    }
242859119e658a12279e8fff508f8773843de2d90917Mathias Agopian
24299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
24309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
243159119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glDeleteTextures(1, &tname);
2432a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    glDisable(GL_TEXTURE_2D);
2433c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_BLEND);
243459119e658a12279e8fff508f8773843de2d90917Mathias Agopian
24359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
24369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
24379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
24389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// ---------------------------------------------------------------------------
24399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2440abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOffImplLocked(int32_t mode)
24419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
244222ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian    ATRACE_CALL();
244322ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian
24441b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    DisplayHardware& hw(const_cast<DisplayHardware&>(getDefaultDisplayHardware()));
24459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (!hw.canDraw()) {
24469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // we're already off
24479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return NO_ERROR;
24489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
24497ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian
24507ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian    // turn off hwc while we're doing the animation
24517ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian    hw.getHwComposer().disable();
24527ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian    // and make sure to turn it back on (if needed) next time we compose
24537ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian    invalidateHwcGeometry();
24547ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian
2455abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    if (mode & ISurfaceComposer::eElectronBeamAnimationOff) {
2456abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        electronBeamOffAnimationImplLocked();
2457abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    }
2458abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian
2459abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    // always clear the whole screen at the end of the animation
2460abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    glClearColor(0,0,0,1);
2461abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    glClear(GL_COLOR_BUFFER_BIT);
2462abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    hw.flip( Region(hw.bounds()) );
2463abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian
2464015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian    return NO_ERROR;
246559119e658a12279e8fff508f8773843de2d90917Mathias Agopian}
246659119e658a12279e8fff508f8773843de2d90917Mathias Agopian
246759119e658a12279e8fff508f8773843de2d90917Mathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOff(int32_t mode)
246859119e658a12279e8fff508f8773843de2d90917Mathias Agopian{
246959119e658a12279e8fff508f8773843de2d90917Mathias Agopian    class MessageTurnElectronBeamOff : public MessageBase {
247059119e658a12279e8fff508f8773843de2d90917Mathias Agopian        SurfaceFlinger* flinger;
2471abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        int32_t mode;
247259119e658a12279e8fff508f8773843de2d90917Mathias Agopian        status_t result;
247359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    public:
2474abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        MessageTurnElectronBeamOff(SurfaceFlinger* flinger, int32_t mode)
2475abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            : flinger(flinger), mode(mode), result(PERMISSION_DENIED) {
247659119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
247759119e658a12279e8fff508f8773843de2d90917Mathias Agopian        status_t getResult() const {
247859119e658a12279e8fff508f8773843de2d90917Mathias Agopian            return result;
247959119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
248059119e658a12279e8fff508f8773843de2d90917Mathias Agopian        virtual bool handler() {
248159119e658a12279e8fff508f8773843de2d90917Mathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
2482abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            result = flinger->turnElectronBeamOffImplLocked(mode);
248359119e658a12279e8fff508f8773843de2d90917Mathias Agopian            return true;
248459119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
248559119e658a12279e8fff508f8773843de2d90917Mathias Agopian    };
248659119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2487abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    sp<MessageBase> msg = new MessageTurnElectronBeamOff(this, mode);
248859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    status_t res = postMessageSync(msg);
248959119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (res == NO_ERROR) {
249059119e658a12279e8fff508f8773843de2d90917Mathias Agopian        res = static_cast<MessageTurnElectronBeamOff*>( msg.get() )->getResult();
24919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
24929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // work-around: when the power-manager calls us we activate the
24939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // animation. eventually, the "on" animation will be called
24949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // by the power-manager itself
2495abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        mElectronBeamAnimationMode = mode;
249659119e658a12279e8fff508f8773843de2d90917Mathias Agopian    }
249759119e658a12279e8fff508f8773843de2d90917Mathias Agopian    return res;
249859119e658a12279e8fff508f8773843de2d90917Mathias Agopian}
249959119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2500edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
2501edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2502abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOnImplLocked(int32_t mode)
25039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
25041b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    DisplayHardware& hw(const_cast<DisplayHardware&>(getDefaultDisplayHardware()));
25059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (hw.canDraw()) {
25069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // we're already on
25079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return NO_ERROR;
25089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
2509abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    if (mode & ISurfaceComposer::eElectronBeamAnimationOn) {
2510abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        electronBeamOnAnimationImplLocked();
2511abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    }
2512a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian
2513a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian    // make sure to redraw the whole screen when the animation is done
2514a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian    mDirtyRegion.set(hw.bounds());
251599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    signalTransaction();
2516a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian
2517015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian    return NO_ERROR;
25189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
25199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
25209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOn(int32_t mode)
25219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
25229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class MessageTurnElectronBeamOn : public MessageBase {
25239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        SurfaceFlinger* flinger;
2524abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        int32_t mode;
25259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        status_t result;
25269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
2527abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        MessageTurnElectronBeamOn(SurfaceFlinger* flinger, int32_t mode)
2528abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            : flinger(flinger), mode(mode), result(PERMISSION_DENIED) {
25299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
25309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        status_t getResult() const {
25319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return result;
25329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
25339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        virtual bool handler() {
25349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
2535abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            result = flinger->turnElectronBeamOnImplLocked(mode);
25369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return true;
25379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
25389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
25399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2540abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    postMessageAsync( new MessageTurnElectronBeamOn(this, mode) );
25419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
25429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
25439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
25449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// ---------------------------------------------------------------------------
25459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
254674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopianstatus_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy,
254774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        sp<IMemoryHeap>* heap,
254874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t* w, uint32_t* h, PixelFormat* f,
2549bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t sw, uint32_t sh,
2550bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ, uint32_t maxLayerZ)
255174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{
2552fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian    ATRACE_CALL();
2553fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian
255474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    status_t result = PERMISSION_DENIED;
255574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
255674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // only one display supported for now
25573b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    if (CC_UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) {
255874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return BAD_VALUE;
25593b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
256074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
25613b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject()) {
256274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return INVALID_OPERATION;
25633b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
256474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
256574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // get screen geometry
25661b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    const DisplayHardware& hw(getDisplayHardware(dpy));
256774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const uint32_t hw_w = hw.getWidth();
256874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const uint32_t hw_h = hw.getHeight();
256974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
25703b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    // if we have secure windows on this display, never allow the screen capture
25713b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    if (hw.getSecureLayerVisible()) {
25723b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        return PERMISSION_DENIED;
25733b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
25743b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
25753b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    if ((sw > hw_w) || (sh > hw_h)) {
257674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return BAD_VALUE;
25773b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
257874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
257974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    sw = (!sw) ? hw_w : sw;
258074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    sh = (!sh) ? hw_h : sh;
258174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const size_t size = sw * sh * 4;
258274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
25839d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block    //ALOGD("screenshot: sw=%d, sh=%d, minZ=%d, maxZ=%d",
25841c71a47a6db679a3212f0c99e14f330d6da500faMathias Agopian    //        sw, sh, minLayerZ, maxLayerZ);
2585c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
258674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // make sure to clear all GL error flags
258774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    while ( glGetError() != GL_NO_ERROR ) ;
258874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
258974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // create a FBO
259074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    GLuint name, tname;
259174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glGenRenderbuffersOES(1, &tname);
259274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindRenderbufferOES(GL_RENDERBUFFER_OES, tname);
259374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA8_OES, sw, sh);
2594fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian
259574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glGenFramebuffersOES(1, &name);
259674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
259774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES,
259874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, tname);
259974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
260074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
2601c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
260274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    if (status == GL_FRAMEBUFFER_COMPLETE_OES) {
260374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
260474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // invert everything, b/c glReadPixel() below will invert the FB
260574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glViewport(0, 0, sw, sh);
260674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_PROJECTION);
260774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glPushMatrix();
260874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glLoadIdentity();
2609ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian        glOrthof(0, hw_w, hw_h, 0, 0, 1);
261074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_MODELVIEW);
261174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
261274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // redraw the screen entirely...
261374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glClearColor(0,0,0,1);
261474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
2615f653b897a449e10d6cbfb6e0812f7b0bb02d6482Mathias Agopian
26169575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        const LayerVector& layers(mDrawingState.layersSortedByZ);
26179575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        const size_t count = layers.size();
261874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        for (size_t i=0 ; i<count ; ++i) {
261974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            const sp<LayerBase>& layer(layers[i]);
2620b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian            const uint32_t flags = layer->drawingState().flags;
2621b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian            if (!(flags & ISurfaceComposer::eLayerHidden)) {
2622b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                const uint32_t z = layer->drawingState().z;
2623b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                if (z >= minLayerZ && z <= maxLayerZ) {
26241b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian                    layer->drawForSreenShot(hw);
2625b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                }
2626bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian            }
262774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        }
262874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
262974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // check for errors and return screen capture
263074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        if (glGetError() != GL_NO_ERROR) {
263174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // error while rendering
263274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            result = INVALID_OPERATION;
263374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        } else {
263474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // allocate shared memory large enough to hold the
263574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // screen capture
263674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            sp<MemoryHeapBase> base(
263774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    new MemoryHeapBase(size, 0, "screen-capture") );
263874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            void* const ptr = base->getBase();
263974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            if (ptr) {
264074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                // capture the screen with glReadPixels()
2641fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian                ScopedTrace _t(ATRACE_TAG, "glReadPixels");
264274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                glReadPixels(0, 0, sw, sh, GL_RGBA, GL_UNSIGNED_BYTE, ptr);
264374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                if (glGetError() == GL_NO_ERROR) {
264474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *heap = base;
264574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *w = sw;
264674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *h = sh;
264774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *f = PIXEL_FORMAT_RGBA_8888;
264874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    result = NO_ERROR;
264974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                }
265074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            } else {
265174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                result = NO_MEMORY;
265274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            }
265374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        }
265474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glViewport(0, 0, hw_w, hw_h);
265574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_PROJECTION);
265674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glPopMatrix();
265774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_MODELVIEW);
265874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    } else {
265974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        result = BAD_VALUE;
266074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    }
266174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
266274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // release FBO resources
266374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
266474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glDeleteRenderbuffersOES(1, &tname);
266574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glDeleteFramebuffersOES(1, &name);
2666e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian
2667e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian    hw.compositionComplete();
2668e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian
26699d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block    // ALOGD("screenshot: result = %s", result<0 ? strerror(result) : "OK");
2670c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
267174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    return result;
267274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian}
267374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
267474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
26751b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopianstatus_t SurfaceFlinger::captureScreen(DisplayID dpy,
26761b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        sp<IMemoryHeap>* heap,
267774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t* width, uint32_t* height, PixelFormat* format,
2678bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t sw, uint32_t sh,
2679bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ, uint32_t maxLayerZ)
26801b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian{
26811b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    // only one display supported for now
268299ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten    if (CC_UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
26831b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        return BAD_VALUE;
26841b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
26851b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
26861b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        return INVALID_OPERATION;
26871b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
26881b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    class MessageCaptureScreen : public MessageBase {
26891b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        SurfaceFlinger* flinger;
26901b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        DisplayID dpy;
26911b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        sp<IMemoryHeap>* heap;
26921b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        uint32_t* w;
26931b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        uint32_t* h;
26941b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        PixelFormat* f;
269574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t sw;
269674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t sh;
2697bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ;
2698bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t maxLayerZ;
26991b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        status_t result;
27001b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    public:
27011b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        MessageCaptureScreen(SurfaceFlinger* flinger, DisplayID dpy,
270274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                sp<IMemoryHeap>* heap, uint32_t* w, uint32_t* h, PixelFormat* f,
2703bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                uint32_t sw, uint32_t sh,
2704bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                uint32_t minLayerZ, uint32_t maxLayerZ)
27051b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            : flinger(flinger), dpy(dpy),
2706bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              heap(heap), w(w), h(h), f(f), sw(sw), sh(sh),
2707bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              minLayerZ(minLayerZ), maxLayerZ(maxLayerZ),
2708bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              result(PERMISSION_DENIED)
27091b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
27101b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
27111b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        status_t getResult() const {
27121b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            return result;
27131b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
27141b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        virtual bool handler() {
27151b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
271674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            result = flinger->captureScreenImplLocked(dpy,
2717bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                    heap, w, h, f, sw, sh, minLayerZ, maxLayerZ);
27181b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            return true;
27191b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
27201b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    };
27211b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
27221b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    sp<MessageBase> msg = new MessageCaptureScreen(this,
2723bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian            dpy, heap, width, height, format, sw, sh, minLayerZ, maxLayerZ);
27241b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    status_t res = postMessageSync(msg);
27251b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    if (res == NO_ERROR) {
27261b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        res = static_cast<MessageCaptureScreen*>( msg.get() )->getResult();
27271b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    }
27281b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    return res;
27291b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian}
27301b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
27311b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// ---------------------------------------------------------------------------
27321b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
2733b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<Layer> SurfaceFlinger::getLayer(const sp<ISurface>& sur) const
2734edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2735b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<Layer> result;
2736b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    Mutex::Autolock _l(mStateLock);
2737b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    result = mLayerMap.valueFor( sur->asBinder() ).promote();
2738b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return result;
2739b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
27407303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
2741b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// ---------------------------------------------------------------------------
274296f0819f81293076e652792794a961543e6750d7Mathias Agopian
27439a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::GraphicBufferAlloc() {}
27449a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
27459a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::~GraphicBufferAlloc() {}
27469a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
27479a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h,
2748d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        PixelFormat format, uint32_t usage, status_t* error) {
27499a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(w, h, format, usage));
27509a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    status_t err = graphicBuffer->initCheck();
2751d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian    *error = err;
2752a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (err != 0 || graphicBuffer->handle == 0) {
2753d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        if (err == NO_MEMORY) {
2754d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian            GraphicBuffer::dumpAllocationsToSystemLog();
2755d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        }
2756e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE("GraphicBufferAlloc::createGraphicBuffer(w=%d, h=%d) "
2757a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian             "failed (%s), handle=%p",
2758a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                w, h, strerror(-err), graphicBuffer->handle);
27599a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis        return 0;
27609a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    }
27619a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    return graphicBuffer;
27629a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis}
27639a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
27649a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis// ---------------------------------------------------------------------------
27659a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
2766edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
2767