SurfaceFlinger.cpp revision c666cae2d5995097ec49a87e375e2afdd92802b7
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 <stdint.h>
20921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <sys/types.h>
21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <errno.h>
22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <math.h>
23921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
24921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <EGL/egl.h>
25921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <GLES/gl.h>
26edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
27edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/log.h>
28edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/properties.h>
29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
30c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IPCThreadState.h>
31c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IServiceManager.h>
327303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian#include <binder/MemoryHeapBase.h>
3399b49840d309727678b77403d6cc9f920111623fMathias Agopian#include <binder/PermissionCache.h>
347303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
35c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian#include <ui/DisplayInfo.h>
36c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian
37d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian#include <gui/IDisplayEventConnection.h>
38921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <gui/BitTube.h>
39921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <gui/SurfaceTextureClient.h>
40921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
41921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <ui/GraphicBufferAllocator.h>
42921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <ui/PixelFormat.h>
43d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
44edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String8.h>
45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String16.h>
46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/StopWatch.h>
471c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#include <utils/Trace.h>
48edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
49921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <private/android_filesystem_config.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
65a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
66bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian#define EGL_VERSION_HW_ANDROID  0x3143
67bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
68edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DISPLAY_COUNT       1
69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
7399b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sHardwareTest("android.permission.HARDWARE_TEST");
7499b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER");
7599b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER");
7699b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sDump("android.permission.DUMP");
7799b49840d309727678b77403d6cc9f920111623fMathias Agopian
7899b49840d309727678b77403d6cc9f920111623fMathias Agopian// ---------------------------------------------------------------------------
7999b49840d309727678b77403d6cc9f920111623fMathias Agopian
80edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::SurfaceFlinger()
81edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    :   BnSurfaceComposer(), Thread(false),
82edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mTransactionFlags(0),
8328378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        mTransationPending(false),
84076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved(false),
85edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mBootTime(systemTime()),
86edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mVisibleRegionsDirty(false),
87a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        mHwWorkListDirty(false),
88abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        mElectronBeamAnimationMode(0),
89edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDebugRegion(0),
908afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian        mDebugDDMS(0),
9173d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian        mDebugDisableHWC(0),
92a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian        mDebugDisableTransformHint(0),
939795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInSwapBuffers(0),
949795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastSwapBufferTime(0),
959795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInTransaction(0),
969795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastTransactionTime(0),
973330b203039dea366d4981db1408a460134b2d2cMathias Agopian        mBootFinished(false),
983094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        mExternalDisplaySurface(EGL_NO_SURFACE)
99edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
100a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI("SurfaceFlinger is starting");
101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // debugging stuff...
103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char value[PROPERTY_VALUE_MAX];
1048afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    property_get("debug.sf.showupdates", value, "0");
106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDebugRegion = atoi(value);
1078afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
1083854ed549012f2abf8fea7b0e6db30b104ea5547Colin Cross#ifdef DDMS_DEBUGGING
1098afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    property_get("debug.sf.ddms", value, "0");
1108afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    mDebugDDMS = atoi(value);
1118afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    if (mDebugDDMS) {
1128afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian        DdmConnection::start(getServiceName());
1138afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    }
1145df996211d4e263feb862121cfafa7f9c8eeda68Mathias Agopian#else
1155df996211d4e263feb862121cfafa7f9c8eeda68Mathias Agopian#warning "DDMS_DEBUGGING disabled"
1163854ed549012f2abf8fea7b0e6db30b104ea5547Colin Cross#endif
1178afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
118a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI_IF(mDebugRegion,       "showupdates enabled");
119a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI_IF(mDebugDDMS,         "DDMS debugging enabled");
120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
12299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::onFirstRef()
12399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
12499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.init(this);
12599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
12699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY);
12799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
12899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // Wait for the main thread to be done with its initialization
12999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mReadyToRunBarrier.wait();
13099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
13199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
13299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::~SurfaceFlinger()
134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDeleteTextures(1, &mWormholeTexName);
136a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
137a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
138a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglTerminate(display);
139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
14199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::binderDied(const wp<IBinder>& who)
14299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
14399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // the window manager died on us. prepare its eulogy.
14499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
14599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // reset screen orientation
14699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    Vector<ComposerState> state;
1478b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian    Vector<DisplayState> displays;
1488b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian    DisplayState d;
1498b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian    d.orientation = eOrientationDefault;
1508b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian    displays.add(d);
1518b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian    setTransactionState(state, displays, 0);
15299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
15399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // restart the boot-animation
154a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    startBootAnim();
15599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
15699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
1577e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopiansp<ISurfaceComposerClient> SurfaceFlinger::createConnection()
158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
15996f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<ISurfaceComposerClient> bclient;
16096f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<Client> client(new Client(this));
16196f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = client->initCheck();
16296f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR) {
16396f0819f81293076e652792794a961543e6750d7Mathias Agopian        bclient = client;
164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return bclient;
166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1689a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc()
1699a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis{
1709a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc());
1719a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    return gba;
1729a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis}
173b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::bootFinished()
175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t now = systemTime();
177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t duration = now - mBootTime;
178a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
1793330b203039dea366d4981db1408a460134b2d2cMathias Agopian    mBootFinished = true;
1801f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
1811f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // wait patiently for the window manager death
1821f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    const String16 name("window");
1831f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    sp<IBinder> window(defaultServiceManager()->getService(name));
1841f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    if (window != 0) {
185921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        window->linkToDeath(static_cast<IBinder::DeathRecipient*>(this));
1861f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    }
1871f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
1881f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // stop boot animation
189a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // formerly we would just kill the process, but we now ask it to exit so it
190a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // can choose where to stop the animation.
191a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("service.bootanim.exit", "1");
192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
194921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianvoid SurfaceFlinger::deleteTextureAsync(GLuint texture) {
195921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    class MessageDestroyGLTexture : public MessageBase {
196921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        GLuint texture;
197921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    public:
198921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        MessageDestroyGLTexture(GLuint texture)
199921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian            : texture(texture) {
200921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        }
201921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        virtual bool handler() {
202921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian            glDeleteTextures(1, &texture);
203921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian            return true;
204921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        }
205921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    };
206921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    postMessageAsync(new MessageDestroyGLTexture(texture));
207921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
208921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
209a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianstatus_t SurfaceFlinger::selectConfigForPixelFormat(
210a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        EGLDisplay dpy,
211a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        EGLint const* attrs,
212a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        PixelFormat format,
213a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        EGLConfig* outConfig)
214a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian{
215a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLConfig config = NULL;
216a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLint numConfigs = -1, n=0;
217a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglGetConfigs(dpy, NULL, 0, &numConfigs);
218a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLConfig* const configs = new EGLConfig[numConfigs];
219a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglChooseConfig(dpy, attrs, configs, numConfigs, &n);
220a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    for (int i=0 ; i<n ; i++) {
221a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        EGLint nativeVisualId = 0;
222a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        eglGetConfigAttrib(dpy, configs[i], EGL_NATIVE_VISUAL_ID, &nativeVisualId);
223a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        if (nativeVisualId>0 && format == nativeVisualId) {
224a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            *outConfig = configs[i];
225a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            delete [] configs;
226a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            return NO_ERROR;
227a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        }
228a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    }
229a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    delete [] configs;
230a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    return NAME_NOT_FOUND;
231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
233a49126087b4494f4ef50873f3a3f6727265f6621Mathias AgopianEGLConfig SurfaceFlinger::selectEGLConfig(EGLDisplay display, EGLint nativeVisualId) {
234a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // select our EGLConfig. It must support EGL_RECORDABLE_ANDROID if
235a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // it is to be used with WIFI displays
236a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLConfig config;
237a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLint dummy;
238a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    status_t err;
239a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLint attribs[] = {
240a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            EGL_SURFACE_TYPE,           EGL_WINDOW_BIT,
241a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            EGL_RECORDABLE_ANDROID,     EGL_TRUE,
242a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            EGL_NONE
243a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    };
244a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    err = selectConfigForPixelFormat(display, attribs, nativeVisualId, &config);
245a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    if (err) {
246a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        // maybe we failed because of EGL_RECORDABLE_ANDROID
247a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        ALOGW("couldn't find an EGLConfig with EGL_RECORDABLE_ANDROID");
248a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        attribs[2] = EGL_NONE;
249a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        err = selectConfigForPixelFormat(display, attribs, nativeVisualId, &config);
250a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    }
251a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGE_IF(err, "couldn't find an EGLConfig matching the screen format");
252a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    if (eglGetConfigAttrib(display, config, EGL_CONFIG_CAVEAT, &dummy) == EGL_TRUE) {
253a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        ALOGW_IF(dummy == EGL_SLOW_CONFIG, "EGL_SLOW_CONFIG selected!");
254a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    }
255a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    return config;
256a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
258a49126087b4494f4ef50873f3a3f6727265f6621Mathias AgopianEGLContext SurfaceFlinger::createGLContext(EGLDisplay display, EGLConfig config) {
259a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // Also create our EGLContext
260a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLint contextAttributes[] = {
261a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#ifdef EGL_IMG_context_priority
262a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#ifdef HAS_CONTEXT_PRIORITY
263a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#warning "using EGL_IMG_context_priority"
264a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_HIGH_IMG,
265a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#endif
266a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#endif
267a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            EGL_NONE, EGL_NONE
268a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    };
269a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLContext ctxt = eglCreateContext(display, config, NULL, contextAttributes);
270a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGE_IF(ctxt==EGL_NO_CONTEXT, "EGLContext creation failed");
271a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    return ctxt;
272a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
274a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianvoid SurfaceFlinger::initializeGL(EGLDisplay display, EGLSurface surface) {
275a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLBoolean result = eglMakeCurrent(display, surface, surface, mEGLContext);
276a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    if (!result) {
277a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        ALOGE("Couldn't create a working GLES context. check logs. exiting...");
278a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        exit(0);
279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
281a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    GLExtensions& extensions(GLExtensions::getInstance());
282a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    extensions.initWithGLStrings(
283a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            glGetString(GL_VENDOR),
284a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            glGetString(GL_RENDERER),
285a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            glGetString(GL_VERSION),
286a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            glGetString(GL_EXTENSIONS),
287a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            eglQueryString(display, EGL_VENDOR),
288a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            eglQueryString(display, EGL_VERSION),
289a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            eglQueryString(display, EGL_EXTENSIONS));
2908b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
291a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLint w, h;
292a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglQuerySurface(display, surface, EGL_WIDTH,  &w);
293a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglQuerySurface(display, surface, EGL_HEIGHT, &h);
2948b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
295a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
296a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    glGetIntegerv(GL_MAX_VIEWPORT_DIMS, mMaxViewportDims);
2977303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
2998b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber    glPixelStorei(GL_PACK_ALIGNMENT, 4);
300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glEnableClientState(GL_VERTEX_ARRAY);
301edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glShadeModel(GL_FLAT);
302edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_DITHER);
303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_CULL_FACE);
304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
305a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    struct pack565 {
306a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        inline uint16_t operator() (int r, int g, int b) const {
307a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            return (r<<11)|(g<<5)|b;
308a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        }
309a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    } pack565;
310a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
311edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint16_t g0 = pack565(0x0F,0x1F,0x0F);
312edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint16_t g1 = pack565(0x17,0x2f,0x17);
3139575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    const uint16_t wormholeTexData[4] = { g0, g1, g1, g0 };
314edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glGenTextures(1, &mWormholeTexName);
315edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glBindTexture(GL_TEXTURE_2D, mWormholeTexName);
316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0,
3219575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis            GL_RGB, GL_UNSIGNED_SHORT_5_6_5, wormholeTexData);
3229575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis
3239575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    const uint16_t protTexData[] = { pack565(0x03, 0x03, 0x03) };
3249575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glGenTextures(1, &mProtectedTexName);
3259575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glBindTexture(GL_TEXTURE_2D, mProtectedTexName);
3269575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3279575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3289575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
3299575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
3309575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0,
3319575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis            GL_RGB, GL_UNSIGNED_SHORT_5_6_5, protTexData);
332edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glViewport(0, 0, w, h);
334edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glMatrixMode(GL_PROJECTION);
335edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glLoadIdentity();
336ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    // put the origin in the left-bottom corner
337ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    glOrthof(0, w, 0, h, 0, 1); // l=0, r=w ; b=0, t=h
338edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
339a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // print some debugging info
340a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLint r,g,b,a;
341a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglGetConfigAttrib(display, mEGLConfig, EGL_RED_SIZE,   &r);
342a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglGetConfigAttrib(display, mEGLConfig, EGL_GREEN_SIZE, &g);
343a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglGetConfigAttrib(display, mEGLConfig, EGL_BLUE_SIZE,  &b);
344a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglGetConfigAttrib(display, mEGLConfig, EGL_ALPHA_SIZE, &a);
345a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("EGL informations:");
346a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("vendor    : %s", extensions.getEglVendor());
347a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("version   : %s", extensions.getEglVersion());
348a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("extensions: %s", extensions.getEglExtension());
349a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("Client API: %s", eglQueryString(display, EGL_CLIENT_APIS)?:"Not Supported");
350a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("EGLSurface: %d-%d-%d-%d, config=%p", r, g, b, a, mEGLConfig);
351a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("OpenGL ES informations:");
352a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("vendor    : %s", extensions.getVendor());
353a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("renderer  : %s", extensions.getRenderer());
354a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("version   : %s", extensions.getVersion());
355a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("extensions: %s", extensions.getExtension());
356a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("GL_MAX_TEXTURE_SIZE = %d", mMaxTextureSize);
357a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("GL_MAX_VIEWPORT_DIMS = %d x %d", mMaxViewportDims[0], mMaxViewportDims[1]);
358a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
359a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
360a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianstatus_t SurfaceFlinger::readyToRun()
361a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian{
362a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI(  "SurfaceFlinger's main thread ready to run. "
363a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            "Initializing graphics H/W...");
364a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
365a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // initialize EGL
366a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
367a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglInitialize(display, NULL, NULL);
368a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
369a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // Initialize the main display
370a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // create native window to main display
371a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    sp<FramebufferSurface> anw = FramebufferSurface::create();
372a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ANativeWindow* const window = anw.get();
373a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    if (!window) {
374a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        ALOGE("Display subsystem failed to initialize. check logs. exiting...");
375a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        exit(0);
376a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    }
377a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
378a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // initialize the config and context
379a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    int format;
380a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    window->query(window, NATIVE_WINDOW_FORMAT, &format);
381a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    mEGLConfig  = selectEGLConfig(display, format);
382a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    mEGLContext = createGLContext(display, mEGLConfig);
383a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
384a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // initialize our main display hardware
385a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    DisplayHardware* const hw = new DisplayHardware(this, 0, anw, mEGLConfig);
386a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    mDisplayHardwares[0] = hw;
387a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
388a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    //  initialize OpenGL ES
389a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLSurface surface = hw->getEGLSurface();
390a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    initializeGL(display, surface);
391d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
392028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian    // start the EventThread
393028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian    mEventThread = new EventThread(this);
394028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian    mEventQueue.setEventThread(mEventThread);
395028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian
3968630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    // initialize the H/W composer
3978630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    mHwc = new HWComposer(this,
3988630320433bd15aca239522e54e711ef6372ab07Mathias Agopian            *static_cast<HWComposer::EventHandler *>(this),
3998630320433bd15aca239522e54e711ef6372ab07Mathias Agopian            hw->getRefreshPeriod());
4008630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    if (mHwc->initCheck() == NO_ERROR) {
4018630320433bd15aca239522e54e711ef6372ab07Mathias Agopian        mHwc->setFrameBuffer(display, surface);
4028630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    }
4038630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
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
471c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopianstatus_t SurfaceFlinger::getDisplayInfo(DisplayID dpy, DisplayInfo* info) {
472c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian    if (uint32_t(dpy) >= 2) {
473c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian        return BAD_INDEX;
474c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian    }
475c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian    const DisplayHardware& hw(getDefaultDisplayHardware());
476c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian    return hw.getInfo(info);
477c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian}
478c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian
479d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian// ----------------------------------------------------------------------------
480d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
481d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopiansp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection() {
4828aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian    return mEventThread->createEventConnection();
483bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian}
484bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
4853094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopianvoid SurfaceFlinger::connectDisplay(const sp<ISurfaceTexture> display) {
4861b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    const DisplayHardware& hw(getDefaultDisplayHardware());
4873094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    EGLSurface result = EGL_NO_SURFACE;
4883094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    EGLSurface old_surface = EGL_NO_SURFACE;
4893094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    sp<SurfaceTextureClient> stc;
4903094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
4913094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    if (display != NULL) {
4923094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        stc = new SurfaceTextureClient(display);
4933094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        result = eglCreateWindowSurface(hw.getEGLDisplay(),
494a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian                mEGLConfig, (EGLNativeWindowType)stc.get(), NULL);
4953094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        ALOGE_IF(result == EGL_NO_SURFACE,
4963094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                "eglCreateWindowSurface failed (ISurfaceTexture=%p)",
4973094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                display.get());
4983094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    }
4993094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
5003094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    { // scope for the lock
5013094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        Mutex::Autolock _l(mStateLock);
5023094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        old_surface = mExternalDisplaySurface;
5033094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        mExternalDisplayNativeWindow = stc;
5043094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        mExternalDisplaySurface = result;
5053094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        ALOGD("mExternalDisplaySurface = %p", result);
5063094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    }
5073094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
5083094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    if (old_surface != EGL_NO_SURFACE) {
5093094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        // Note: EGL allows to destroy an object while its current
5103094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        // it will fail to become current next time though.
5113094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        eglDestroySurface(hw.getEGLDisplay(), old_surface);
5123094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    }
5133094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian}
5143094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
5153094df359d1e6e2ae8ca4e935cc093f563804c96Mathias AgopianEGLSurface SurfaceFlinger::getExternalDisplaySurface() const {
5163094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    Mutex::Autolock _l(mStateLock);
5173094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    return mExternalDisplaySurface;
5183094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian}
5193094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
520edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
52199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
52299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::waitForEvent() {
52399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.waitMessage();
52499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
52599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
52699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalTransaction() {
52799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.invalidate();
52899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
52999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
53099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalLayerUpdate() {
53199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.invalidate();
53299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
53399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
53499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalRefresh() {
53599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.refresh();
53699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
53799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
53899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg,
53999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        nsecs_t reltime, uint32_t flags) {
54099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return mEventQueue.postMessage(msg, reltime);
54199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
54299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
54399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,
54499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        nsecs_t reltime, uint32_t flags) {
54599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    status_t res = mEventQueue.postMessage(msg, reltime);
54699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    if (res == NO_ERROR) {
54799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        msg->wait();
54899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    }
54999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return res;
55099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
551edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5524fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianbool SurfaceFlinger::threadLoop() {
553edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    waitForEvent();
55499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return true;
55599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
556edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5578630320433bd15aca239522e54e711ef6372ab07Mathias Agopianvoid SurfaceFlinger::onVSyncReceived(int dpy, nsecs_t timestamp) {
5588630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    DisplayHardware& hw(const_cast<DisplayHardware&>(getDisplayHardware(dpy)));
5598630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    hw.onVSyncReceived(timestamp);
5608630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    mEventThread->onVSyncReceived(dpy, timestamp);
5618630320433bd15aca239522e54e711ef6372ab07Mathias Agopian}
5628630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
5638630320433bd15aca239522e54e711ef6372ab07Mathias Agopianvoid SurfaceFlinger::eventControl(int event, int enabled) {
5648630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    getHwComposer().eventControl(event, enabled);
5658630320433bd15aca239522e54e711ef6372ab07Mathias Agopian}
5668630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
5674fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::onMessageReceived(int32_t what) {
5681c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
56999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    switch (what) {
5704fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    case MessageQueue::INVALIDATE:
5714fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        handleMessageTransaction();
5724fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        handleMessageInvalidate();
5734fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        signalRefresh();
5744fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        break;
5754fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    case MessageQueue::REFRESH:
5764fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        handleMessageRefresh();
5774fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        break;
5784fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
5794fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
580edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5814fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageTransaction() {
5824fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
5834fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    uint32_t transactionFlags = peekTransactionFlags(mask);
5844fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    if (transactionFlags) {
5854fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        Region dirtyRegion;
5864fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        dirtyRegion = handleTransaction(transactionFlags);
5874fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // XXX: dirtyRegion should be per screen
5884fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        mDirtyRegion |= dirtyRegion;
5894fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
5904fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
591edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5924fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageInvalidate() {
5934fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    Region dirtyRegion;
5944fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    dirtyRegion = handlePageFlip();
5954fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    // XXX: dirtyRegion should be per screen
5964fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mDirtyRegion |= dirtyRegion;
5974fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
5983a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian
5994fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageRefresh() {
6004fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    handleRefresh();
601a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
6023b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    if (mVisibleRegionsDirty) {
6033b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        Region opaqueRegion;
6043b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        Region dirtyRegion;
6053b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
6063b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        computeVisibleRegions(currentLayers, dirtyRegion, opaqueRegion);
6073b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        mDirtyRegion.orSelf(dirtyRegion);
6083b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
6093b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        /*
6103b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian         *  rebuild the visible layer list per screen
6113b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian         */
6123b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
6133b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        // TODO: iterate through all displays
6143b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        DisplayHardware& hw(const_cast<DisplayHardware&>(getDisplayHardware(0)));
6153b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
6163b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        Vector< sp<LayerBase> > layersSortedByZ;
6173b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        const size_t count = currentLayers.size();
6183b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        for (size_t i=0 ; i<count ; i++) {
6193b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian            if (!currentLayers[i]->visibleRegion.isEmpty()) {
6203b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian                // TODO: also check that this layer is associated to this display
6213b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian                layersSortedByZ.add(currentLayers[i]);
6223b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian            }
6233b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        }
6243b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        hw.setVisibleLayersSortedByZ(layersSortedByZ);
6253b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
6263b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
6273b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        // FIXME: mWormholeRegion needs to be calculated per screen
6283b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        //const DisplayHardware& hw(getDefaultDisplayHardware()); // XXX: we can't keep that here
6293b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        mWormholeRegion = Region(hw.getBounds()).subtract(
6303b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian                hw.getTransform().transform(opaqueRegion) );
6313b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        mVisibleRegionsDirty = false;
6323b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        invalidateHwcGeometry();
6333b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
6343b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
6353b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
6364fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    // XXX: dirtyRegion should be per screen, we should check all of them
6374fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    if (mDirtyRegion.isEmpty()) {
6384fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        return;
6394fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
640303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian
6414fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    // TODO: iterate through all displays
6424fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    const DisplayHardware& hw(getDisplayHardware(0));
64369a655caef30663403802281210363f643ceb946Mathias Agopian
6444fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    // XXX: dirtyRegion should be per screen
6454fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    // transform the dirty region into this screen's coordinate space
6464fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    const Transform& planeTransform(hw.getTransform());
6474fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mDirtyRegion = planeTransform.transform(mDirtyRegion);
6484fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mDirtyRegion.orSelf(getAndClearInvalidateRegion());
6494fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mDirtyRegion.andSelf(hw.bounds());
650303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian
651b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian
6524fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    if (CC_UNLIKELY(mHwWorkListDirty)) {
6534fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // build the h/w work list
6544fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        handleWorkList(hw);
6554fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
6563094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
6574fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    if (CC_LIKELY(hw.canDraw())) {
6584fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // repaint the framebuffer (if needed)
6594fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        handleRepaint(hw);
6604fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // inform the h/w that we're done compositing
6614fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        hw.compositionComplete();
6624fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        postFramebuffer();
6634fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    } else {
6644fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // pretend we did the post
6654fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        hw.compositionComplete();
6664fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
6673094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
6684fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    // render to the external display if we have one
6694fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    EGLSurface externalDisplaySurface = getExternalDisplaySurface();
6704fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    if (externalDisplaySurface != EGL_NO_SURFACE) {
6714fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        EGLSurface cur = eglGetCurrentSurface(EGL_DRAW);
6724fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        EGLBoolean success = eglMakeCurrent(eglGetCurrentDisplay(),
6734fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                externalDisplaySurface, externalDisplaySurface,
6744fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                eglGetCurrentContext());
6754fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
6764fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        ALOGE_IF(!success, "eglMakeCurrent -> external failed");
6774fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
6784fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        if (success) {
6794fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            // redraw the screen entirely...
6804fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            glDisable(GL_TEXTURE_EXTERNAL_OES);
6814fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            glDisable(GL_TEXTURE_2D);
6824fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            glClearColor(0,0,0,1);
6834fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            glClear(GL_COLOR_BUFFER_BIT);
6844fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            glMatrixMode(GL_MODELVIEW);
6854fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            glLoadIdentity();
6863b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
6873b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian            const Vector< sp<LayerBase> >& layers( hw.getVisibleLayersSortedByZ() );
6884fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const size_t count = layers.size();
6894fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            for (size_t i=0 ; i<count ; ++i) {
6904fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                const sp<LayerBase>& layer(layers[i]);
6914fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                layer->drawForSreenShot(hw);
6924fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            }
6933094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
6944fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            success = eglSwapBuffers(eglGetCurrentDisplay(), externalDisplaySurface);
6954fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            ALOGE_IF(!success, "external display eglSwapBuffers failed");
6963094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
6974fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            hw.compositionComplete();
6984fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        }
6993094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
7004fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        success = eglMakeCurrent(eglGetCurrentDisplay(),
7014fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                cur, cur, eglGetCurrentContext());
7024fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
7034fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        ALOGE_IF(!success, "eglMakeCurrent -> internal failed");
704edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
7054fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
706edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
707edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
708edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer()
709edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
710841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
711b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian    // mSwapRegion can be empty here is some cases, for instance if a hidden
712b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian    // or fully transparent window is updating.
713b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian    // in that case, we need to flip anyways to not risk a deadlock with
714b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian    // h/w composer.
715b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian
7161b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    const DisplayHardware& hw(getDefaultDisplayHardware());
7178630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    HWComposer& hwc(getHwComposer());
7183b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    const Vector< sp<LayerBase> >& layers(hw.getVisibleLayersSortedByZ());
7193b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    size_t numLayers = layers.size();
720a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    const nsecs_t now = systemTime();
721a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = now;
722c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall
723c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall    if (hwc.initCheck() == NO_ERROR) {
724c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall        HWComposer::LayerListIterator cur = hwc.begin();
725c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall        const HWComposer::LayerListIterator end = hwc.end();
726c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall        for (size_t i = 0; cur != end && i < numLayers; ++i, ++cur) {
727c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall            if (cur->getCompositionType() == HWC_OVERLAY) {
7283b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian                layers[i]->setAcquireFence(*cur);
729c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall            } else {
730c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall                cur->setAcquireFenceFd(-1);
731c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall            }
732c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall        }
733c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall    }
734c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall
735a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    hw.flip(mSwapRegion);
7368630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    hwc.commit();
737e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
738ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall    if (hwc.initCheck() == NO_ERROR) {
739ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall        HWComposer::LayerListIterator cur = hwc.begin();
740ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall        const HWComposer::LayerListIterator end = hwc.end();
741ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall        for (size_t i = 0; cur != end && i < numLayers; ++i, ++cur) {
7423b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian            layers[i]->onLayerDisplayed(&*cur);
743ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall        }
744ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall    } else {
745ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall        for (size_t i = 0; i < numLayers; i++) {
7463b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian            layers[i]->onLayerDisplayed(NULL);
747ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall        }
748e8696a40e09b24b634214684d18526187b316a2fJamie Gennis    }
749e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
750a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mLastSwapBufferTime = systemTime() - now;
751a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = 0;
752a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mSwapRegion.clear();
753edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
754edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
7554fec873a98f7b4380720cd1ad006f74c8cdc73daMathias AgopianRegion SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
756edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
757841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
758841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
7594fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    Region dirtyRegion;
7604fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
761ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    Mutex::Autolock _l(mStateLock);
762ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    const nsecs_t now = systemTime();
763ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = now;
764ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
765ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // Here we're guaranteed that some transaction flags are set
766ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // so we can call handleTransactionLocked() unconditionally.
767ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // We call getTransactionFlags(), which will also clear the flags,
768ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // with mStateLock held to guarantee that mCurrentState won't change
769ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // until the transaction is committed.
770ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
771ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
772ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    transactionFlags = getTransactionFlags(mask);
7734fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    dirtyRegion = handleTransactionLocked(transactionFlags);
774ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
775ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mLastTransactionTime = systemTime() - now;
776ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = 0;
777ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    invalidateHwcGeometry();
778ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // here the transaction has been committed
7794fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
7804fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    return dirtyRegion;
7813d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian}
782edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
7834fec873a98f7b4380720cd1ad006f74c8cdc73daMathias AgopianRegion SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
7843d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{
7854fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    Region dirtyRegion;
7863d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    const LayerVector& currentLayers(mCurrentState.layersSortedByZ);
787edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t count = currentLayers.size();
788edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
789edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
790edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Traversal of the children
791edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * (perform the transaction for each of them if needed)
792edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
793edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
794edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const bool layersNeedTransaction = transactionFlags & eTraversalNeeded;
795edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (layersNeedTransaction) {
796edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (size_t i=0 ; i<count ; i++) {
797076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            const sp<LayerBase>& layer = currentLayers[i];
798edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
799edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (!trFlags) continue;
800edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
801edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const uint32_t flags = layer->doTransaction(0);
802edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (flags & Layer::eVisibleRegion)
803edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mVisibleRegionsDirty = true;
804edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
805edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
806edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
807edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
808edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Perform our own transaction if needed
809edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
810edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
811edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (transactionFlags & eTransactionNeeded) {
812edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (mCurrentState.orientation != mDrawingState.orientation) {
813edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // the orientation has changed, recompute all visible regions
814edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // and invalidate everything.
815edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
8161b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian            const int dpy = 0; // TODO: should be a parameter
8171b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian            DisplayHardware& hw(const_cast<DisplayHardware&>(getDisplayHardware(dpy)));
81898a121aa916eb7acbf11df0e3e31a6fede6fc9ddMathias Agopian            hw.setOrientation(mCurrentState.orientation);
819edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
8201b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian            // FIXME: mVisibleRegionsDirty & mDirtyRegion should this be per DisplayHardware?
821edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
822edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mDirtyRegion.set(hw.bounds());
823edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
824edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
8250aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        if (currentLayers.size() > mDrawingState.layersSortedByZ.size()) {
8260aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            // layers have been added
827edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
828edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
829edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
8300aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        // some layers might have been removed, so
8310aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        // we need to update the regions they're exposing.
8320aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        if (mLayersRemoved) {
83348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian            mLayersRemoved = false;
834edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
8350aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            const LayerVector& previousLayers(mDrawingState.layersSortedByZ);
8363d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian            const size_t count = previousLayers.size();
8373d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian            for (size_t i=0 ; i<count ; i++) {
8380aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                const sp<LayerBase>& layer(previousLayers[i]);
8390aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                if (currentLayers.indexOf( layer ) < 0) {
8400aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                    // this layer is not visible anymore
8414fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    // TODO: we could traverse the tree from front to back and compute the actual visible region
8424fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    // TODO: we could cache the transformed region
8434fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    Layer::State front(layer->drawingState());
8444fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    Region visibleReg = front.transform.transform(
8454fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            Region(Rect(front.active.w, front.active.h)));
8464fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    dirtyRegion.orSelf(visibleReg);
8470aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                }
8480aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            }
849edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
850edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
851edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
852edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    commitTransaction();
8534fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    return dirtyRegion;
8544fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
8554fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
8564fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::commitTransaction()
8574fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian{
8584fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    if (!mLayersPendingRemoval.isEmpty()) {
8594fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // Notify removed layers now that they can't be drawn from
8604fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        for (size_t i = 0; i < mLayersPendingRemoval.size(); i++) {
8614fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            mLayersPendingRemoval[i]->onRemoved();
8624fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        }
8634fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        mLayersPendingRemoval.clear();
8644fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
8654fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
8664fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mDrawingState = mCurrentState;
8674fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mTransationPending = false;
8684fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mTransactionCV.broadcast();
869edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
870edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
871edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::computeVisibleRegions(
8721bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian    const LayerVector& currentLayers, Region& dirtyRegion, Region& opaqueRegion)
873edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
874841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
875841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
876edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveOpaqueLayers;
877edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveCoveredLayers;
878edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region dirty;
879edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
8803b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    dirtyRegion.clear();
881edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
882edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t i = currentLayers.size();
883edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    while (i--) {
884076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        const sp<LayerBase>& layer = currentLayers[i];
885edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
886edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // start with the whole surface at its current location
887970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian        const Layer::State& s(layer->drawingState());
888edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
889ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
890ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * opaqueRegion: area of a surface that is fully opaque.
891ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
892edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region opaqueRegion;
893ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
894ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
895ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visibleRegion: area of a surface that is visible on screen
896ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * and not fully transparent. This is essentially the layer's
897ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * footprint minus the opaque regions above it.
898ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * Areas covered by a translucent surface are considered visible.
899ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
900edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region visibleRegion;
901ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
902ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
903ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * coveredRegion: area of a surface that is covered by all
904ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visible regions above it (which includes the translucent areas).
905ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
906edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region coveredRegion;
907ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
908ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
909ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // handle hidden surfaces by setting the visible region to empty
91099ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten        if (CC_LIKELY(!(s.flags & ISurfaceComposer::eLayerHidden) && s.alpha)) {
911a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            const bool translucent = !layer->isOpaque();
9124fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            Rect bounds(layer->computeBounds());
913edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            visibleRegion.set(bounds);
914ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            if (!visibleRegion.isEmpty()) {
915ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // Remove the transparent area from the visible region
916ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (translucent) {
9174fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    Region transparentRegionScreen;
9184fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    const Transform tr(s.transform);
9194fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    if (tr.transformed()) {
9204fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                        if (tr.preserveRects()) {
9214fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            // transform the transparent region
9224fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            transparentRegionScreen = tr.transform(s.transparentRegion);
9234fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                        } else {
9244fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            // transformation too complex, can't do the
9254fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            // transparent region optimization.
9264fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            transparentRegionScreen.clear();
9274fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                        }
9284fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    } else {
9294fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                        transparentRegionScreen = s.transparentRegion;
9304fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    }
9314fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    visibleRegion.subtractSelf(transparentRegionScreen);
932ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
933edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
934ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // compute the opaque region
9354fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                const int32_t layerOrientation = s.transform.getOrientation();
936ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (s.alpha==255 && !translucent &&
937ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                        ((layerOrientation & Transform::ROT_INVALID) == false)) {
938ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    // the opaque region is the layer's footprint
939ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    opaqueRegion = visibleRegion;
940ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
941edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
942edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
943edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
944ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Clip the covered region to the visible region
945ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        coveredRegion = aboveCoveredLayers.intersect(visibleRegion);
946ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
947ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveCoveredLayers for next (lower) layer
948ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        aboveCoveredLayers.orSelf(visibleRegion);
949ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
950edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // subtract the opaque region covered by the layers above us
951edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        visibleRegion.subtractSelf(aboveOpaqueLayers);
952edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
953edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // compute this layer's dirty region
954edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (layer->contentDirty) {
955edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // we need to invalidate the whole region
956edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dirty = visibleRegion;
957edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // as well, as the old visible region
9584fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            dirty.orSelf(layer->visibleRegion);
959edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->contentDirty = false;
960edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
961a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian            /* compute the exposed region:
962ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   the exposed region consists of two components:
963ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   1) what's VISIBLE now and was COVERED before
964ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   2) what's EXPOSED now less what was EXPOSED before
965ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
966ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * note that (1) is conservative, we start with the whole
967ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * visible region but only keep what used to be covered by
968ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * something -- which mean it may have been exposed.
969ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
970ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * (2) handles areas that were not covered by anything but got
971ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * exposed because of a resize.
972a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian             */
973ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region newExposed = visibleRegion - coveredRegion;
9744fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region oldVisibleRegion = layer->visibleRegion;
9754fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region oldCoveredRegion = layer->coveredRegion;
976ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldExposed = oldVisibleRegion - oldCoveredRegion;
977ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed);
978edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
979edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirty.subtractSelf(aboveOpaqueLayers);
980edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
981edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // accumulate to the screen dirty region
982edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirtyRegion.orSelf(dirty);
983edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
984ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveOpaqueLayers for next (lower) layer
985edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        aboveOpaqueLayers.orSelf(opaqueRegion);
9868b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
987edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // Store the visible region is screen space
988edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setVisibleRegion(visibleRegion);
989edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setCoveredRegion(coveredRegion);
990edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
991edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
992edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    opaqueRegion = aboveOpaqueLayers;
993edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
994edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
9954fec873a98f7b4380720cd1ad006f74c8cdc73daMathias AgopianRegion SurfaceFlinger::handlePageFlip()
996edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
9971c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
9984fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    Region dirtyRegion;
99999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
10001bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian    const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
1001edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
10024fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    bool visibleRegions = false;
10034fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    const size_t count = currentLayers.size();
10044fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    sp<LayerBase> const* layers = currentLayers.array();
10054fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    for (size_t i=0 ; i<count ; i++) {
10064fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        const sp<LayerBase>& layer(layers[i]);
10074fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        dirtyRegion.orSelf( layer->latchBuffer(visibleRegions) );
10084fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
10094da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
10103b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    mVisibleRegionsDirty |= visibleRegions;
10110dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian
10124fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    return dirtyRegion;
1013edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1014edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1015ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopianvoid SurfaceFlinger::invalidateHwcGeometry()
1016ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian{
1017ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian    mHwWorkListDirty = true;
1018ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian}
1019ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian
102099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::handleRefresh()
102199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
102299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    bool needInvalidate = false;
102399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
102499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    const size_t count = currentLayers.size();
102599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
102699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
102799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        if (layer->onPreComposition()) {
102899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            needInvalidate = true;
102999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        }
103099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    }
103199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    if (needInvalidate) {
103299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        signalLayerUpdate();
103399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    }
103499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
103599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
103699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
10371b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopianvoid SurfaceFlinger::handleWorkList(const DisplayHardware& hw)
1038a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian{
1039a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    mHwWorkListDirty = false;
10408630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    HWComposer& hwc(getHwComposer());
1041a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    if (hwc.initCheck() == NO_ERROR) {
10423b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        const Vector< sp<LayerBase> >& currentLayers(hw.getVisibleLayersSortedByZ());
1043a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        const size_t count = currentLayers.size();
1044a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        hwc.createWorkList(count);
10453e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian
10463e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian        HWComposer::LayerListIterator cur = hwc.begin();
10473e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian        const HWComposer::LayerListIterator end = hwc.end();
10483e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian        for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
10494fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            currentLayers[i]->setGeometry(hw, *cur);
105053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian            if (mDebugDisableHWC || mDebugRegion) {
10513e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian                cur->setSkip(true);
105273d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian            }
1053a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        }
1054a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
1055a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian}
1056b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian
10571b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopianvoid SurfaceFlinger::handleRepaint(const DisplayHardware& hw)
1058edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1059841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
1060841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
1061b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // compute the invalid region
10620656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian    mSwapRegion.orSelf(mDirtyRegion);
1063edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
106499ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten    if (CC_UNLIKELY(mDebugRegion)) {
10651b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian        debugFlashRegions(hw);
1066edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1067edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1068b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // set the frame buffer
1069b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    glMatrixMode(GL_MODELVIEW);
1070b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    glLoadIdentity();
1071edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1072edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t flags = hw.getFlags();
1073a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian    if (flags & DisplayHardware::SWAP_RECTANGLE) {
107429d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // we can redraw only what's dirty, but since SWAP_RECTANGLE only
107529d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // takes a rectangle, we must make sure to update that whole
107629d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // rectangle in that case
1077a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        mDirtyRegion.set(mSwapRegion.bounds());
1078edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
107995a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian        if (flags & DisplayHardware::PARTIAL_UPDATES) {
108029d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // We need to redraw the rectangle that will be updated
1081df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian            // (pushed to the framebuffer).
108295a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian            // This is needed because PARTIAL_UPDATES only takes one
108329d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // rectangle instead of a region (see DisplayHardware::flip())
10840656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian            mDirtyRegion.set(mSwapRegion.bounds());
1085edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
108629d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // we need to redraw everything (the whole screen)
1087edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mDirtyRegion.set(hw.bounds());
10880656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian            mSwapRegion = mDirtyRegion;
1089edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1090edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1091edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
10921b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    setupHardwareComposer(hw);
10931b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    composeSurfaces(hw, mDirtyRegion);
1094edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
10959c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    // update the swap region and clear the dirty region
10969c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    mSwapRegion.orSelf(mDirtyRegion);
1097edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDirtyRegion.clear();
1098edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1099edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
11001b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopianvoid SurfaceFlinger::setupHardwareComposer(const DisplayHardware& hw)
1101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
11028630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    HWComposer& hwc(getHwComposer());
11033e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    HWComposer::LayerListIterator cur = hwc.begin();
11043e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    const HWComposer::LayerListIterator end = hwc.end();
11053e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    if (cur == end) {
11069c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        return;
1107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1108a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
11093b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    const Vector< sp<LayerBase> >& layers(hw.getVisibleLayersSortedByZ());
111045721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    size_t count = layers.size();
1111a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
1112e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block    ALOGE_IF(hwc.getNumLayers() != count,
111345721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            "HAL number of layers (%d) doesn't match surfaceflinger (%d)",
111445721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            hwc.getNumLayers(), count);
1115a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
111645721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    // just to be extra-safe, use the smallest count
111724925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling    if (hwc.initCheck() == NO_ERROR) {
111824925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling        count = count < hwc.getNumLayers() ? count : hwc.getNumLayers();
111924925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling    }
1120a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
112145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    /*
112245721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     *  update the per-frame h/w composer data for each layer
112345721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     *  and build the transparent region of the FB
112445721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     */
11253e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
1126f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
11273e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian        layer->setPerFrameData(*cur);
1128f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    }
1129f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    status_t err = hwc.prepare();
1130e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block    ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
1131f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian}
1132f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian
11331b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopianvoid SurfaceFlinger::composeSurfaces(const DisplayHardware& hw, const Region& dirty)
1134f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian{
11358630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    HWComposer& hwc(getHwComposer());
11363e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    HWComposer::LayerListIterator cur = hwc.begin();
11373e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    const HWComposer::LayerListIterator end = hwc.end();
1138cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian
1139cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian    const size_t fbLayerCount = hwc.getLayerCount(HWC_FRAMEBUFFER);
11403e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    if (cur==end || fbLayerCount) {
1141a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        // Never touch the framebuffer if we don't have any framebuffer layers
114245721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian
1143b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian        if (hwc.getLayerCount(HWC_OVERLAY)) {
1144b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // when using overlays, we assume a fully transparent framebuffer
1145b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // NOTE: we could reduce how much we need to clear, for instance
1146b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // remove where there are opaque FB layers. however, on some
1147b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // GPUs doing a "clean slate" glClear might be more efficient.
1148b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // We'll revisit later if needed.
1149b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            glClearColor(0, 0, 0, 0);
1150b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            glClear(GL_COLOR_BUFFER_BIT);
1151b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian        } else {
1152b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // screen is already cleared here
1153b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            if (!mWormholeRegion.isEmpty()) {
1154b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                // can happen with SurfaceView
1155b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                drawWormhole();
1156b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            }
1157a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        }
11584b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian
1159a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        /*
1160a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian         * and then, render the layers targeted at the framebuffer
1161a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian         */
11624b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian
11633b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        const Vector< sp<LayerBase> >& layers(hw.getVisibleLayersSortedByZ());
1164a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        const size_t count = layers.size();
11654fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        const Transform& tr = hw.getTransform();
1166a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall        for (size_t i=0 ; i<count ; ++i) {
1167a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian            const sp<LayerBase>& layer(layers[i]);
11684fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region clip(dirty.intersect(tr.transform(layer->visibleRegion)));
1169a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian            if (!clip.isEmpty()) {
1170a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall                if (cur != end && cur->getCompositionType() == HWC_OVERLAY) {
11713e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian                    if (i && (cur->getHints() & HWC_HINT_CLEAR_FB)
1172a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                            && layer->isOpaque()) {
1173b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                        // never clear the very first layer since we're
1174b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                        // guaranteed the FB is already cleared
11751b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian                        layer->clearWithOpenGL(hw, clip);
1176a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                    }
11776ee93c0d36dff1339eb2428be2d65441398e6e5fJesse Hall                    ++cur;
1178a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                    continue;
1179a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                }
1180a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                // render the layer
11811b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian                layer->draw(hw, clip);
11824b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian            }
1183a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall            if (cur != end) {
1184a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall                ++cur;
1185a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall            }
11864b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian        }
11874b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian    }
1188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
11901b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopianvoid SurfaceFlinger::debugFlashRegions(const DisplayHardware& hw)
1191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
11920a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    const uint32_t flags = hw.getFlags();
119353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian    const int32_t height = hw.getHeight();
11940656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian    if (mSwapRegion.isEmpty()) {
119553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian        return;
119653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian    }
11970a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
1198a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian    if (!(flags & DisplayHardware::SWAP_RECTANGLE)) {
11990a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        const Region repaint((flags & DisplayHardware::PARTIAL_UPDATES) ?
12000a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian                mDirtyRegion.bounds() : hw.bounds());
12011b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian        composeSurfaces(hw, repaint);
12020a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    }
12030a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
1204c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_EXTERNAL_OES);
1205c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_2D);
1206edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_BLEND);
1207edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
12080926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    static int toggle = 0;
12090926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    toggle = 1 - toggle;
12100926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    if (toggle) {
12110a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        glColor4f(1, 0, 1, 1);
12120926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    } else {
12130a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        glColor4f(1, 1, 0, 1);
12140926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    }
1215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
121620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    Region::const_iterator it = mDirtyRegion.begin();
121720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    Region::const_iterator const end = mDirtyRegion.end();
121820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    while (it != end) {
121920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        const Rect& r = *it++;
1220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLfloat vertices[][2] = {
122153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.left,  height - r.top },
122253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.left,  height - r.bottom },
122353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.right, height - r.bottom },
122453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.right, height - r.top }
1225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        };
1226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glVertexPointer(2, GL_FLOAT, 0, vertices);
1227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
12290a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
12300656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian    hw.flip(mSwapRegion);
1231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mDebugRegion > 1)
12330a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        usleep(mDebugRegion * 1000);
1234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::drawWormhole() const
1237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Region region(mWormholeRegion.intersect(mDirtyRegion));
1239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (region.isEmpty())
1240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1242f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    glDisable(GL_TEXTURE_EXTERNAL_OES);
1243b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian    glDisable(GL_TEXTURE_2D);
1244f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    glDisable(GL_BLEND);
1245b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian    glColor4f(0,0,0,0);
1246f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian
1247f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    GLfloat vertices[4][2];
1248f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    glVertexPointer(2, GL_FLOAT, 0, vertices);
1249f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    Region::const_iterator it = region.begin();
1250f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    Region::const_iterator const end = region.end();
1251f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    while (it != end) {
1252f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        const Rect& r = *it++;
1253f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[0][0] = r.left;
1254f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[0][1] = r.top;
1255f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[1][0] = r.right;
1256f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[1][1] = r.top;
1257f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[2][0] = r.right;
1258f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[2][1] = r.bottom;
1259f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[3][0] = r.left;
1260f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[3][1] = r.bottom;
1261f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1262f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    }
1263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
126596f0819f81293076e652792794a961543e6750d7Mathias Agopianssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
126696f0819f81293076e652792794a961543e6750d7Mathias Agopian        const sp<LayerBaseClient>& lbc)
12671b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
126896f0819f81293076e652792794a961543e6750d7Mathias Agopian    // attach this layer to the client
12694f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    size_t name = client->attachLayer(lbc);
12704f113740180b6512b43723c4728f262882dc9b45Mathias Agopian
127196f0819f81293076e652792794a961543e6750d7Mathias Agopian    // add this layer to the current state list
1272921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    Mutex::Autolock _l(mStateLock);
1273921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    mCurrentState.layersSortedByZ.add(lbc);
127496f0819f81293076e652792794a961543e6750d7Mathias Agopian
12754f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    return ssize_t(name);
127696f0819f81293076e652792794a961543e6750d7Mathias Agopian}
127796f0819f81293076e652792794a961543e6750d7Mathias Agopian
127896f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer)
127996f0819f81293076e652792794a961543e6750d7Mathias Agopian{
128096f0819f81293076e652792794a961543e6750d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
128196f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = purgatorizeLayer_l(layer);
128296f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR)
128396f0819f81293076e652792794a961543e6750d7Mathias Agopian        setTransactionFlags(eTransactionNeeded);
128496f0819f81293076e652792794a961543e6750d7Mathias Agopian    return err;
1285edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1286edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1287076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase)
1288edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1289edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase);
1290edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (index >= 0) {
1291076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved = true;
1292edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
1293edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
12943d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    return status_t(index);
1295edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
12979a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase)
12989a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
129976cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    // First add the layer to the purgatory list, which makes sure it won't
130076cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    // go away, then remove it from the main list (through a transaction).
13019a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    ssize_t err = removeLayer_l(layerBase);
130276cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    if (err >= 0) {
130376cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian        mLayerPurgatory.add(layerBase);
130476cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    }
13058c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian
13062f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall    mLayersPendingRemoval.push(layerBase);
13070b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian
13083d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // it's possible that we don't find a layer, because it might
13093d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // have been destroyed already -- this is not technically an error
131096f0819f81293076e652792794a961543e6750d7Mathias Agopian    // from the user because there is a race between Client::destroySurface(),
131196f0819f81293076e652792794a961543e6750d7Mathias Agopian    // ~Client() and ~ISurface().
13129a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err;
13139a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
13149a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
1315dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopianuint32_t SurfaceFlinger::peekTransactionFlags(uint32_t flags)
1316dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian{
1317dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian    return android_atomic_release_load(&mTransactionFlags);
1318dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian}
1319dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian
1320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags)
1321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return android_atomic_and(~flags, &mTransactionFlags) & flags;
1323edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1324edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1325bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags)
1326edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1327edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t old = android_atomic_or(flags, &mTransactionFlags);
1328edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((old & flags)==0) { // wake the server up
132999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        signalTransaction();
1330edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1331edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return old;
1332edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1334edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
13358b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopianvoid SurfaceFlinger::setTransactionState(
13368b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        const Vector<ComposerState>& state,
13378b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        const Vector<DisplayState>& displays,
13388b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        uint32_t flags)
13398b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian{
1340698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
1341cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
13428b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian    int orientation = eOrientationUnchanged;
13438b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian    if (displays.size()) {
13448b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        // TODO: handle all displays
13458b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        orientation = displays[0].orientation;
13468b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian    }
13478b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian
134828378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    uint32_t transactionFlags = 0;
1349b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis    if (mCurrentState.orientation != orientation) {
1350b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis        if (uint32_t(orientation)<=eOrientation270 || orientation==42) {
1351b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis            mCurrentState.orientation = orientation;
135228378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis            transactionFlags |= eTransactionNeeded;
1353b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis        } else if (orientation != eOrientationUnchanged) {
135432397c1cd3327905173b36baa6fd1c579bc328ffSteve Block            ALOGW("setTransactionState: ignoring unrecognized orientation: %d",
1355b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis                    orientation);
1356b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis        }
1357b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis    }
1358b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis
1359698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    const size_t count = state.size();
1360698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
1361698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const ComposerState& s(state[i]);
1362698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        sp<Client> client( static_cast<Client *>(s.client.get()) );
136328378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        transactionFlags |= setClientStateLocked(client, s.state);
1364698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    }
1365386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian
136628378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    if (transactionFlags) {
1367386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // this triggers the transaction
136828378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        setTransactionFlags(transactionFlags);
1369698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian
1370386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // if this is a synchronous transaction, wait for it to take effect
1371386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // before returning.
1372386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        if (flags & eSynchronous) {
1373386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            mTransationPending = true;
1374386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        }
1375386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        while (mTransationPending) {
1376386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
1377386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            if (CC_UNLIKELY(err != NO_ERROR)) {
1378386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                // just in case something goes wrong in SF, return to the
1379386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                // called after a few seconds.
138032397c1cd3327905173b36baa6fd1c579bc328ffSteve Block                ALOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!");
1381386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                mTransationPending = false;
1382386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                break;
1383386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            }
1384cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        }
1385edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1386edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1387edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1388921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopiansp<ISurface> SurfaceFlinger::createLayer(
13890ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        ISurfaceComposerClient::surface_data_t* params,
13900ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const String8& name,
13910ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const sp<Client>& client,
1392edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        DisplayID d, uint32_t w, uint32_t h, PixelFormat format,
1393edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t flags)
1394edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1395076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBaseClient> layer;
1396a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    sp<ISurface> surfaceHandle;
13976e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian
13986e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    if (int32_t(w|h) < 0) {
1399921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        ALOGE("createLayer() failed, w or h is negative (w=%d, h=%d)",
14006e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian                int(w), int(h));
14016e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian        return surfaceHandle;
14026e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    }
14038b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
1404921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    //ALOGD("createLayer for (%d x %d), name=%s", w, h, name.string());
1405edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (flags & eFXSurfaceMask) {
1406edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceNormal:
1407921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian            layer = createNormalLayer(client, d, w, h, flags, format);
1408edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
1409edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceBlur:
14101293a8eb567fd63c072a6970fa9dcf37d076059fMathias Agopian            // for now we treat Blur as Dim, until we can implement it
14111293a8eb567fd63c072a6970fa9dcf37d076059fMathias Agopian            // efficiently.
1412edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceDim:
1413921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian            layer = createDimLayer(client, d, w, h, flags);
1414edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
1415118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        case eFXSurfaceScreenshot:
1416921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian            layer = createScreenshotLayer(client, d, w, h, flags);
1417118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian            break;
1418edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1419edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1420076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (layer != 0) {
142196f0819f81293076e652792794a961543e6750d7Mathias Agopian        layer->initStates(w, h, flags);
1422285dbde2e0cd0057be070ded3be8f5f453147edcMathias Agopian        layer->setName(name);
142396f0819f81293076e652792794a961543e6750d7Mathias Agopian        ssize_t token = addClientLayer(client, layer);
1424edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        surfaceHandle = layer->getSurface();
14258b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber        if (surfaceHandle != 0) {
142696f0819f81293076e652792794a961543e6750d7Mathias Agopian            params->token = token;
1427a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            params->identity = layer->getIdentity();
14281c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        }
142996f0819f81293076e652792794a961543e6750d7Mathias Agopian        setTransactionFlags(eTransactionNeeded);
1430edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1431edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1432edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return surfaceHandle;
1433edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1434edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1435921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopiansp<Layer> SurfaceFlinger::createNormalLayer(
1436f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        const sp<Client>& client, DisplayID display,
143796f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags,
14381c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        PixelFormat& format)
1439edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1440edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize the surfaces
1441edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (format) { // TODO: take h/w into account
1442edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSPARENT:
1443edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSLUCENT:
1444edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        format = PIXEL_FORMAT_RGBA_8888;
1445edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1446edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_OPAQUE:
1447a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888
1448a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian        format = PIXEL_FORMAT_RGB_565;
1449a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#else
14508f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian        format = PIXEL_FORMAT_RGBX_8888;
1451a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif
1452edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1453edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1454edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1455a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888
1456a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian    if (format == PIXEL_FORMAT_RGBX_8888)
1457a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian        format = PIXEL_FORMAT_RGBA_8888;
1458a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif
1459a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian
146096f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<Layer> layer = new Layer(this, display, client);
1461f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian    status_t err = layer->setBuffers(w, h, format, flags);
146299ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten    if (CC_LIKELY(err != NO_ERROR)) {
1463921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        ALOGE("createNormalLayer() failed (%s)", strerror(-err));
1464076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        layer.clear();
1465edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1466edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1467edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1468edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1469921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopiansp<LayerDim> SurfaceFlinger::createDimLayer(
1470f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        const sp<Client>& client, DisplayID display,
147196f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags)
1472edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
147396f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<LayerDim> layer = new LayerDim(this, display, client);
1474118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    return layer;
1475118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
1476118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
1477921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopiansp<LayerScreenshot> SurfaceFlinger::createScreenshotLayer(
1478118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        const sp<Client>& client, DisplayID display,
1479118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags)
1480118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{
1481118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    sp<LayerScreenshot> layer = new LayerScreenshot(this, display, client);
1482edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1483edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1484edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1485921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianstatus_t SurfaceFlinger::onLayerRemoved(const sp<Client>& client, SurfaceID sid)
14869a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
14879a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    /*
14889a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     * called by the window manager, when a surface should be marked for
14899a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     * destruction.
14908b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber     *
14910aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * The surface is removed from the current and drawing lists, but placed
14920aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * in the purgatory queue, so it's not destroyed right-away (we need
14930aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * to wait for all client's references to go away first).
14949a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     */
14959a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
149648d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    status_t err = NAME_NOT_FOUND;
14970aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian    Mutex::Autolock _l(mStateLock);
149896f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<LayerBaseClient> layer = client->getLayerUser(sid);
1499b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam
150048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    if (layer != 0) {
150148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        err = purgatorizeLayer_l(layer);
150248d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        if (err == NO_ERROR) {
150348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian            setTransactionFlags(eTransactionNeeded);
150448d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        }
15059a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    }
15069a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return err;
15079a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
15089a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
1509921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianstatus_t SurfaceFlinger::onLayerDestroyed(const wp<LayerBaseClient>& layer)
1510edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1511759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian    // called by ~ISurface() when all references are gone
1512ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    status_t err = NO_ERROR;
1513ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    sp<LayerBaseClient> l(layer.promote());
1514ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    if (l != NULL) {
1515ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        Mutex::Autolock _l(mStateLock);
1516ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        err = removeLayer_l(l);
1517ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        if (err == NAME_NOT_FOUND) {
1518ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // The surface wasn't in the current list, which means it was
1519ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // removed already, which means it is in the purgatory,
1520ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // and need to be removed from there.
1521ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            ssize_t idx = mLayerPurgatory.remove(l);
1522e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block            ALOGE_IF(idx < 0,
1523ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian                    "layer=%p is not in the purgatory list", l.get());
1524f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        }
1525e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE_IF(err<0 && err != NAME_NOT_FOUND,
1526ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian                "error removing layer=%p (%s)", l.get(), strerror(-err));
1527ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    }
1528ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    return err;
1529edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1530edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1531698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopianuint32_t SurfaceFlinger::setClientStateLocked(
153296f0819f81293076e652792794a961543e6750d7Mathias Agopian        const sp<Client>& client,
1533698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const layer_state_t& s)
1534edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1535edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t flags = 0;
1536698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    sp<LayerBaseClient> layer(client->getLayerUser(s.surface));
1537698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    if (layer != 0) {
1538698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const uint32_t what = s.what;
1539698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & ePositionChanged) {
1540698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setPosition(s.x, s.y))
1541698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1542698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1543698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eLayerChanged) {
1544698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
1545698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setLayer(s.z)) {
1546698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                mCurrentState.layersSortedByZ.removeAt(idx);
1547698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                mCurrentState.layersSortedByZ.add(layer);
1548698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                // we need traversal (state changed)
1549698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                // AND transaction (list changed)
1550698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTransactionNeeded|eTraversalNeeded;
1551edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1552698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1553698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eSizeChanged) {
1554698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setSize(s.w, s.h)) {
1555698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1556edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1557edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1558698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eAlphaChanged) {
1559698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f)))
1560698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1561698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1562698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eMatrixChanged) {
1563698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setMatrix(s.matrix))
1564698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1565698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1566698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eTransparentRegionChanged) {
1567698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setTransparentRegionHint(s.transparentRegion))
1568698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1569698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1570698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eVisibilityChanged) {
1571698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setFlags(s.flags, s.mask))
1572698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1573698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1574f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        if (what & eCropChanged) {
1575f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis            if (layer->setCrop(s.crop))
1576f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis                flags |= eTraversalNeeded;
1577f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        }
15788785578391eacd4192333d7b0ce3afedd7d163e6Mathias Agopian        if (what & eLayerStackChanged) {
15798785578391eacd4192333d7b0ce3afedd7d163e6Mathias Agopian            if (layer->setLayerStack(s.layerStack))
15808785578391eacd4192333d7b0ce3afedd7d163e6Mathias Agopian                flags |= eTraversalNeeded;
15818785578391eacd4192333d7b0ce3afedd7d163e6Mathias Agopian        }
1582edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1583698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    return flags;
1584edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1585edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1586b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// ---------------------------------------------------------------------------
1587b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
1588b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopianvoid SurfaceFlinger::onScreenAcquired() {
15898e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross    ALOGD("Screen about to return, flinger = %p", this);
15901b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    const DisplayHardware& hw(getDefaultDisplayHardware()); // XXX: this should be per DisplayHardware
15918630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    getHwComposer().acquire();
1592b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    hw.acquireScreen();
159322ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian    mEventThread->onScreenAcquired();
1594b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    // this is a temporary work-around, eventually this should be called
1595b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    // by the power-manager
1596b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    SurfaceFlinger::turnElectronBeamOn(mElectronBeamAnimationMode);
159722ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian    // from this point on, SF will process updates again
15988acce2046ac7086c3dcfb1fc7c9c39f31de48694Mathias Agopian    repaintEverything();
1599edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1600edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1601b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopianvoid SurfaceFlinger::onScreenReleased() {
16028e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross    ALOGD("About to give-up screen, flinger = %p", this);
16031b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    const DisplayHardware& hw(getDefaultDisplayHardware()); // XXX: this should be per DisplayHardware
1604b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    if (hw.isScreenAcquired()) {
160522ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian        mEventThread->onScreenReleased();
1606b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        hw.releaseScreen();
16078630320433bd15aca239522e54e711ef6372ab07Mathias Agopian        getHwComposer().release();
1608b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        // from this point on, SF will stop drawing
1609b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    }
1610b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian}
1611b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
16128e533069e5721e55cb9768e140e16546c3a4a8b6Colin Crossvoid SurfaceFlinger::unblank() {
1613b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    class MessageScreenAcquired : public MessageBase {
1614b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        SurfaceFlinger* flinger;
1615b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    public:
1616b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        MessageScreenAcquired(SurfaceFlinger* flinger) : flinger(flinger) { }
1617b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        virtual bool handler() {
1618b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            flinger->onScreenAcquired();
1619b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            return true;
1620b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        }
1621b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    };
1622b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    sp<MessageBase> msg = new MessageScreenAcquired(this);
1623b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    postMessageSync(msg);
1624edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1625edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
16268e533069e5721e55cb9768e140e16546c3a4a8b6Colin Crossvoid SurfaceFlinger::blank() {
1627b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    class MessageScreenReleased : public MessageBase {
1628b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        SurfaceFlinger* flinger;
1629b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    public:
1630b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        MessageScreenReleased(SurfaceFlinger* flinger) : flinger(flinger) { }
1631b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        virtual bool handler() {
1632b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            flinger->onScreenReleased();
1633b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            return true;
1634b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        }
1635b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    };
1636b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    sp<MessageBase> msg = new MessageScreenReleased(this);
1637b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    postMessageSync(msg);
1638b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian}
1639b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
1640b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// ---------------------------------------------------------------------------
1641b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
1642edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
1643edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
16441d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling    const size_t SIZE = 4096;
1645edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char buffer[SIZE];
1646edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    String8 result;
164799b49840d309727678b77403d6cc9f920111623fMathias Agopian
164899b49840d309727678b77403d6cc9f920111623fMathias Agopian    if (!PermissionCache::checkCallingPermission(sDump)) {
1649edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        snprintf(buffer, SIZE, "Permission Denial: "
1650edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                "can't dump SurfaceFlinger from pid=%d, uid=%d\n",
1651edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                IPCThreadState::self()->getCallingPid(),
1652edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                IPCThreadState::self()->getCallingUid());
1653edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        result.append(buffer);
1654edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
16559795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // Try to get the main lock, but don't insist if we can't
16569795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // (this would indicate SF is stuck, but we want to be able to
16579795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // print something in dumpsys).
16589795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        int retry = 3;
16599795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        while (mStateLock.tryLock()<0 && --retry>=0) {
16609795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            usleep(1000000);
16619795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
16629795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const bool locked(retry >= 0);
16639795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (!locked) {
16648b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber            snprintf(buffer, SIZE,
16659795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "SurfaceFlinger appears to be unresponsive, "
16669795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "dumping anyways (no locks held)\n");
16679795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            result.append(buffer);
16689795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
16699795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
167082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        bool dumpAll = true;
167182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        size_t index = 0;
167225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        size_t numArgs = args.size();
167325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        if (numArgs) {
167425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
167525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--list"))) {
167625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                index++;
167725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                listLayersLocked(args, index, result, buffer, SIZE);
167835aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
167925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            }
168025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
168125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
168225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--latency"))) {
168382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                index++;
168482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                dumpStatsLocked(args, index, result, buffer, SIZE);
168535aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
168682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            }
168725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
168825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
168925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--latency-clear"))) {
169025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                index++;
169125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                clearStatsLocked(args, index, result, buffer, SIZE);
169235aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
169325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            }
1694edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
16951b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
169682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (dumpAll) {
169782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            dumpAllLocked(result, buffer, SIZE);
169882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
169948b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
170082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (locked) {
170182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mStateLock.unlock();
170248b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        }
170382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
170482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    write(fd, result.string(), result.size());
170582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    return NO_ERROR;
170682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
170748b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
170825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::listLayersLocked(const Vector<String16>& args, size_t& index,
170925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        String8& result, char* buffer, size_t SIZE) const
171025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
171125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
171225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const size_t count = currentLayers.size();
171325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
171425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
171525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        snprintf(buffer, SIZE, "%s\n", layer->getName().string());
171625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        result.append(buffer);
171725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
171825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
171925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
172082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index,
172182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        String8& result, char* buffer, size_t SIZE) const
172282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
172382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    String8 name;
172482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    if (index < args.size()) {
172582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        name = String8(args[index]);
172682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        index++;
172782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
172848b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
172982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
173082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const size_t count = currentLayers.size();
173182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    for (size_t i=0 ; i<count ; i++) {
173282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
173382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (name.isEmpty()) {
173482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            snprintf(buffer, SIZE, "%s\n", layer->getName().string());
173582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            result.append(buffer);
173682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
173782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (name.isEmpty() || (name == layer->getName())) {
173882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            layer->dumpStats(result, buffer, SIZE);
173982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
174082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
174182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
1742ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian
174325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& index,
174425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        String8& result, char* buffer, size_t SIZE) const
174525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
174625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    String8 name;
174725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    if (index < args.size()) {
174825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        name = String8(args[index]);
174925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        index++;
175025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
175125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
175225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
175325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const size_t count = currentLayers.size();
175425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
175525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
175625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        if (name.isEmpty() || (name == layer->getName())) {
175725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            layer->clearStats();
175825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        }
175925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
176025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
176125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
176282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpAllLocked(
176382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        String8& result, char* buffer, size_t SIZE) const
176482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
176582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    // figure out if we're stuck somewhere
176682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t now = systemTime();
176782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t inSwapBuffers(mDebugInSwapBuffers);
176882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t inTransaction(mDebugInTransaction);
176982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0;
177082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0;
1771bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
177282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
177382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump the visible layer list
177482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
177582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
177682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const size_t count = currentLayers.size();
177782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "Visible layers (count = %d)\n", count);
177882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
177982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    for (size_t i=0 ; i<count ; i++) {
178082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
178182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        layer->dump(result, buffer, SIZE);
178282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
1783bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
178482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
178582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump the layers in the purgatory
178682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
1787ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian
178882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const size_t purgatorySize = mLayerPurgatory.size();
178982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "Purgatory state (%d entries)\n", purgatorySize);
179082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
179182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    for (size_t i=0 ; i<purgatorySize ; i++) {
179282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
179382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        layer->shortDump(result, buffer, SIZE);
179482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
17951b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
179682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
179782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump SurfaceFlinger global state
179882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
17991b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
180082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "SurfaceFlinger global state:\n");
180182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
18021b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
18031b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    const DisplayHardware& hw(getDefaultDisplayHardware());
180482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const GLExtensions& extensions(GLExtensions::getInstance());
180582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "GLES: %s, %s, %s\n",
180682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            extensions.getVendor(),
180782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            extensions.getRenderer(),
180882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            extensions.getVersion());
180982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
1810d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
181182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "EGL : %s\n",
18121b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian            eglQueryString(hw.getEGLDisplay(),
181382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                    EGL_VERSION_HW_ANDROID));
181482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
181573d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian
181682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "EXTS: %s\n", extensions.getExtension());
181782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
18189795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
181982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    mWormholeRegion.dump(result, "WormholeRegion");
182082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE,
182182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  orientation=%d, canDraw=%d\n",
182282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mCurrentState.orientation, hw.canDraw());
182382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
182482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE,
182582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  last eglSwapBuffers() time: %f us\n"
182682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  last transaction time     : %f us\n"
1827c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian            "  transaction-flags         : %08x\n"
182882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  refresh-rate              : %f fps\n"
182982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  x-dpi                     : %f\n"
1830b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian            "  y-dpi                     : %f\n"
1831b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian            "  density                   : %f\n",
183282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mLastSwapBufferTime/1000.0,
183382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mLastTransactionTime/1000.0,
1834c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian            mTransactionFlags,
183582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            hw.getRefreshRate(),
183682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            hw.getDpiX(),
1837b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian            hw.getDpiY(),
1838b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian            hw.getDensity());
183982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
184082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
184182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "  eglSwapBuffers time: %f us\n",
184282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            inSwapBuffersDuration/1000.0);
184382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
184482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
184582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "  transaction time: %f us\n",
184682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            inTransactionDuration/1000.0);
184782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
184882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
184982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
185082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * VSYNC state
185182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
185282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    mEventThread->dump(result, buffer, SIZE);
185382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
185482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
185582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump HWComposer state
185682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
18578630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    HWComposer& hwc(getHwComposer());
185882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "h/w composer state:\n");
185982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
186082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "  h/w composer %s and %s\n",
186182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            hwc.initCheck()==NO_ERROR ? "present" : "not present",
186282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                    (mDebugDisableHWC || mDebugRegion) ? "disabled" : "enabled");
186382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
18643b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    hwc.dump(result, buffer, SIZE, hw.getVisibleLayersSortedByZ());
186582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
186682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
186782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump gralloc state
186882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
186982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
187082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    alloc.dump(result);
187182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    hw.dump(result);
1872edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1873edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1874edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::onTransact(
1875edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
1876edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1877edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (code) {
1878edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case CREATE_CONNECTION:
1879698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        case SET_TRANSACTION_STATE:
1880edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case SET_ORIENTATION:
1881edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case BOOT_FINISHED:
188259119e658a12279e8fff508f8773843de2d90917Mathias Agopian        case TURN_ELECTRON_BEAM_OFF:
18839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        case TURN_ELECTRON_BEAM_ON:
18848e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross        case BLANK:
18858e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross        case UNBLANK:
1886edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        {
1887edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // codes that require permission check
1888edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            IPCThreadState* ipc = IPCThreadState::self();
1889edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int pid = ipc->getCallingPid();
1890a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian            const int uid = ipc->getCallingUid();
189199b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
189299b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) {
1893e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block                ALOGE("Permission Denial: "
1894375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                        "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
1895375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                return PERMISSION_DENIED;
1896edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
18971b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
18981b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
18991b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        case CAPTURE_SCREEN:
19001b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
19011b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            // codes that require permission check
19021b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
19031b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int pid = ipc->getCallingPid();
19041b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int uid = ipc->getCallingUid();
190599b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
190699b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) {
1907e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block                ALOGE("Permission Denial: "
19081b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                        "can't read framebuffer pid=%d, uid=%d", pid, uid);
19091b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                return PERMISSION_DENIED;
19101b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            }
19111b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
1912edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1913edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
19141b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
1915edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
1916edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
1917b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        CHECK_INTERFACE(ISurfaceComposer, data, reply);
191899ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten        if (CC_UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) {
1919375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
1920375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int pid = ipc->getCallingPid();
1921375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int uid = ipc->getCallingUid();
1922e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block            ALOGE("Permission Denial: "
1923375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                    "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
1924edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return PERMISSION_DENIED;
1925edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1926edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int n;
1927edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        switch (code) {
192801b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian            case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE
192935b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian            case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE
1930edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1931edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1002:  // SHOW_UPDATES
1932edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                n = data.readInt32();
1933edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDebugRegion = n ? n : (mDebugRegion ? 0 : 1);
193453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
193553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
1936edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1937edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1004:{ // repaint everything
193853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
1939cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
1940cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            }
1941cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            case 1005:{ // force transaction
1942cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
1943cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
1944edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
19454d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            case 1006:{ // send empty update
19464d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian                signalRefresh();
19474d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian                return NO_ERROR;
19484d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            }
194953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian            case 1008:  // toggle use of hw composer
195053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                n = data.readInt32();
195153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                mDebugDisableHWC = n ? 1 : 0;
195253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
195353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
195453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                return NO_ERROR;
1955a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian            case 1009:  // toggle use of transform hint
1956a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                n = data.readInt32();
1957a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                mDebugDisableTransformHint = n ? 1 : 0;
1958a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                invalidateHwcGeometry();
1959a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                repaintEverything();
1960a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                return NO_ERROR;
1961edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1010:  // interrogate.
196201b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian                reply->writeInt32(0);
1963edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(0);
1964edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(mDebugRegion);
1965b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                reply->writeInt32(0);
196612839bee29bdcc65731b4d42029cc59e2320c5c4Dianne Hackborn                reply->writeInt32(mDebugDisableHWC);
1967edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1968edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1013: {
1969edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                Mutex::Autolock _l(mStateLock);
19701b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian                const DisplayHardware& hw(getDefaultDisplayHardware());
1971edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(hw.getPageFlipCount());
1972edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1973edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return NO_ERROR;
1974edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1975edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1976edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return err;
1977edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1978edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
197953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopianvoid SurfaceFlinger::repaintEverything() {
19801b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    const DisplayHardware& hw(getDefaultDisplayHardware()); // FIXME: this cannot be bound the default display
19810dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    const Rect bounds(hw.getBounds());
19820dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    setInvalidateRegion(Region(bounds));
198399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    signalTransaction();
198453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian}
198553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian
19860dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopianvoid SurfaceFlinger::setInvalidateRegion(const Region& reg) {
19870dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    Mutex::Autolock _l(mInvalidateLock);
19880dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    mInvalidateRegion = reg;
19890dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian}
19900dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian
19910dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias AgopianRegion SurfaceFlinger::getAndClearInvalidateRegion() {
19920dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    Mutex::Autolock _l(mInvalidateLock);
19930dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    Region reg(mInvalidateRegion);
19940dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    mInvalidateRegion.clear();
19950dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    return reg;
19960dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian}
19970dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian
199859119e658a12279e8fff508f8773843de2d90917Mathias Agopian// ---------------------------------------------------------------------------
199959119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2000118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopianstatus_t SurfaceFlinger::renderScreenToTexture(DisplayID dpy,
2001118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        GLuint* textureName, GLfloat* uOut, GLfloat* vOut)
2002118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{
2003118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    Mutex::Autolock _l(mStateLock);
2004118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    return renderScreenToTextureLocked(dpy, textureName, uOut, vOut);
2005118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
2006118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
20079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::renderScreenToTextureLocked(DisplayID dpy,
20089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        GLuint* textureName, GLfloat* uOut, GLfloat* vOut)
200959119e658a12279e8fff508f8773843de2d90917Mathias Agopian{
201022ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian    ATRACE_CALL();
201122ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian
201259119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
201359119e658a12279e8fff508f8773843de2d90917Mathias Agopian        return INVALID_OPERATION;
201459119e658a12279e8fff508f8773843de2d90917Mathias Agopian
201559119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // get screen geometry
20161b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    const DisplayHardware& hw(getDisplayHardware(dpy));
201759119e658a12279e8fff508f8773843de2d90917Mathias Agopian    const uint32_t hw_w = hw.getWidth();
201859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    const uint32_t hw_h = hw.getHeight();
201959119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLfloat u = 1;
202059119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLfloat v = 1;
202159119e658a12279e8fff508f8773843de2d90917Mathias Agopian
202259119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // make sure to clear all GL error flags
202359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    while ( glGetError() != GL_NO_ERROR ) ;
202459119e658a12279e8fff508f8773843de2d90917Mathias Agopian
202559119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // create a FBO
202659119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLuint name, tname;
202759119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glGenTextures(1, &tname);
202859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
2029a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2030a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
20319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
20329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            hw_w, hw_h, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
203359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (glGetError() != GL_NO_ERROR) {
2034015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian        while ( glGetError() != GL_NO_ERROR ) ;
203559119e658a12279e8fff508f8773843de2d90917Mathias Agopian        GLint tw = (2 << (31 - clz(hw_w)));
203659119e658a12279e8fff508f8773843de2d90917Mathias Agopian        GLint th = (2 << (31 - clz(hw_h)));
20379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
20389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian                tw, th, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
203959119e658a12279e8fff508f8773843de2d90917Mathias Agopian        u = GLfloat(hw_w) / tw;
204059119e658a12279e8fff508f8773843de2d90917Mathias Agopian        v = GLfloat(hw_h) / th;
204159119e658a12279e8fff508f8773843de2d90917Mathias Agopian    }
204259119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glGenFramebuffersOES(1, &name);
204359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
20449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES,
20459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0);
204659119e658a12279e8fff508f8773843de2d90917Mathias Agopian
20479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // redraw the screen entirely...
2048c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_EXTERNAL_OES);
2049c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_2D);
20509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glClearColor(0,0,0,1);
20519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glClear(GL_COLOR_BUFFER_BIT);
2052a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glMatrixMode(GL_MODELVIEW);
2053a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glLoadIdentity();
20543b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    const Vector< sp<LayerBase> >& layers(hw.getVisibleLayersSortedByZ());
20559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const size_t count = layers.size();
20569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (size_t i=0 ; i<count ; ++i) {
20579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
20581b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian        layer->drawForSreenShot(hw);
20599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
206059119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2061118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    hw.compositionComplete();
2062118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
20639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // back to main framebuffer
20649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
20659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDeleteFramebuffersOES(1, &name);
206659119e658a12279e8fff508f8773843de2d90917Mathias Agopian
20679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *textureName = tname;
20689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *uOut = u;
20699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *vOut = v;
20709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
20719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
207259119e658a12279e8fff508f8773843de2d90917Mathias Agopian
20739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// ---------------------------------------------------------------------------
207459119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2075ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopianclass VSyncWaiter {
2076ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    DisplayEventReceiver::Event buffer[4];
2077ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    sp<Looper> looper;
2078ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    sp<IDisplayEventConnection> events;
2079ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    sp<BitTube> eventTube;
2080ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopianpublic:
2081ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    VSyncWaiter(const sp<EventThread>& eventThread) {
2082ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        looper = new Looper(true);
2083ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        events = eventThread->createEventConnection();
2084ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        eventTube = events->getDataChannel();
2085ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        looper->addFd(eventTube->getFd(), 0, ALOOPER_EVENT_INPUT, 0, 0);
2086ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        events->requestNextVsync();
2087ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    }
2088ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
2089ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    void wait() {
2090ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        ssize_t n;
2091ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
2092ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        looper->pollOnce(-1);
2093ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        // we don't handle any errors here, it doesn't matter
2094ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        // and we don't want to take the risk to get stuck.
2095ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
2096ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        // drain the events...
2097ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        while ((n = DisplayEventReceiver::getEvents(
2098ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian                eventTube, buffer, 4)) > 0) ;
2099ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
2100ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        events->requestNextVsync();
2101ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    }
2102ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian};
2103ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
21049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::electronBeamOffAnimationImplLocked()
21059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
21069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // get screen geometry
21071b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    const DisplayHardware& hw(getDefaultDisplayHardware());
21089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_w = hw.getWidth();
21099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_h = hw.getHeight();
2110a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    const Region screenBounds(hw.getBounds());
211159119e658a12279e8fff508f8773843de2d90917Mathias Agopian
21129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat u, v;
21139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLuint tname;
2114118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    status_t result = renderScreenToTextureLocked(0, &tname, &u, &v);
21159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (result != NO_ERROR) {
21169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return result;
21179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
211859119e658a12279e8fff508f8773843de2d90917Mathias Agopian
21199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat vtx[8];
2120a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    const GLfloat texCoords[4][2] = { {0,0}, {0,v}, {u,v}, {u,0} };
21219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
21229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
21239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
21249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2125b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2126b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
21279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
21289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
21299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glVertexPointer(2, GL_FLOAT, 0, vtx);
21309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2131ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    /*
2132ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     * Texture coordinate mapping
2133ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *
2134ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *                 u
2135ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *    1 +----------+---+
2136ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |     |    |   |  image is inverted
2137ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |     V    |   |  w.r.t. the texture
2138ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *  1-v +----------+   |  coordinates
2139ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |              |
2140ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |              |
2141ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |              |
2142ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *    0 +--------------+
2143ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      0              1
2144ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *
2145ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     */
2146ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian
21479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class s_curve_interpolator {
21489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float nbFrames, s, v;
21499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
21509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        s_curve_interpolator(int nbFrames, float s)
21519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : nbFrames(1.0f / (nbFrames-1)), s(s),
21529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian          v(1.0f + expf(-s + 0.5f*s)) {
21539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
21549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float operator()(int f) {
21559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const float x = f * nbFrames;
21569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f;
21579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
21589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
21599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class v_stretch {
21619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
21629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
21639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        v_stretch(uint32_t hw_w, uint32_t hw_h)
21649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
21659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
21669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
21679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w + (hw_w * v);
21689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = hw_h - (hw_h * v);
21699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
21709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
2171ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[0] = x;         vtx[1] = y;
2172ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
2173ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
2174ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
21759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
21769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
21779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class h_stretch {
21799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
21809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
21819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        h_stretch(uint32_t hw_w, uint32_t hw_h)
21829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
218359119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
21849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
21859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w - (hw_w * v);
21869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = 1.0f;
21879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
21889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
2189ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[0] = x;         vtx[1] = y;
2190ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
2191ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
2192ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
21939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
21949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
21959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2196ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    VSyncWaiter vsync(mEventThread);
2197ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
21989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // the full animation is 24 frames
2199ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    char value[PROPERTY_VALUE_MAX];
2200ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    property_get("debug.sf.electron_frames", value, "24");
2201ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    int nbFrames = (atoi(value) + 1) >> 1;
2202ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    if (nbFrames <= 0) // just in case
2203ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian        nbFrames = 24;
2204ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian
22059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itr(nbFrames, 7.5f);
22069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itg(nbFrames, 8.0f);
22079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itb(nbFrames, 8.5f);
22089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    v_stretch vverts(hw_w, hw_h);
2210a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian
2211a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glMatrixMode(GL_TEXTURE);
2212a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glLoadIdentity();
2213a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glMatrixMode(GL_MODELVIEW);
2214a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glLoadIdentity();
2215a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian
22169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnable(GL_BLEND);
22179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBlendFunc(GL_ONE, GL_ONE);
22189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=0 ; i<nbFrames ; i++) {
22199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float x, y, w, h;
22209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vr = itr(i);
22219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vg = itg(i);
22229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vb = itb(i);
22239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2224ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        // wait for vsync
2225ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        vsync.wait();
2226ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
22279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // clear screen
22289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(1,1,1,1);
22299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
22309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glEnable(GL_TEXTURE_2D);
223159119e658a12279e8fff508f8773843de2d90917Mathias Agopian
22329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the red plane
22339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vr);
22349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(1,0,0,1);
22359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
22369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the green plane
22389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vg);
22399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,1,0,1);
22409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
22419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the blue plane
22439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vb);
22449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,0,1,1);
22459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
22469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the white highlight (we use the last vertices)
224859119e658a12279e8fff508f8773843de2d90917Mathias Agopian        glDisable(GL_TEXTURE_2D);
224959119e658a12279e8fff508f8773843de2d90917Mathias Agopian        glColorMask(1,1,1,1);
22509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColor4f(vg, vg, vg, 1);
22519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
22529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
22539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
22549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    h_stretch hverts(hw_w, hw_h);
22569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_BLEND);
22579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_TEXTURE_2D);
22589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
22599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=0 ; i<nbFrames ; i++) {
22609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float v = itg(i);
22619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hverts(vtx, v);
2262ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
2263ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        // wait for vsync
2264ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        vsync.wait();
2265ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
22669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
22679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColor4f(1-v, 1-v, 1-v, 1);
22689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
22699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
22709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
22719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
22739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
22749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDeleteTextures(1, &tname);
2275a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    glDisable(GL_TEXTURE_2D);
2276c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_BLEND);
22779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
22789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
22799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::electronBeamOnAnimationImplLocked()
22819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
22829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    status_t result = PERMISSION_DENIED;
22839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
22859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return INVALID_OPERATION;
22869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // get screen geometry
22891b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    const DisplayHardware& hw(getDefaultDisplayHardware());
22909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_w = hw.getWidth();
22919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_h = hw.getHeight();
22929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const Region screenBounds(hw.bounds());
22939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat u, v;
22959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLuint tname;
22969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    result = renderScreenToTextureLocked(0, &tname, &u, &v);
22979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (result != NO_ERROR) {
22989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return result;
22999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
23009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
23019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat vtx[8];
23029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const GLfloat texCoords[4][2] = { {0,v}, {0,0}, {u,0}, {u,v} };
23039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
23049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
23059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
23069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2307b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2308b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
23099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
23109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
23119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glVertexPointer(2, GL_FLOAT, 0, vtx);
23129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
23139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class s_curve_interpolator {
23149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float nbFrames, s, v;
23159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
23169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        s_curve_interpolator(int nbFrames, float s)
23179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : nbFrames(1.0f / (nbFrames-1)), s(s),
23189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian          v(1.0f + expf(-s + 0.5f*s)) {
23199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
23209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float operator()(int f) {
23219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const float x = f * nbFrames;
23229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f;
23239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
23249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
23259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
23269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class v_stretch {
23279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
23289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
23299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        v_stretch(uint32_t hw_w, uint32_t hw_h)
23309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
233159119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
23329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
23339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w + (hw_w * v);
23349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = hw_h - (hw_h * v);
23359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
23369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
23379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[0] = x;         vtx[1] = y;
23389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
23399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
23409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
23419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
23429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
23439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
23449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class h_stretch {
23459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
23469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
23479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        h_stretch(uint32_t hw_w, uint32_t hw_h)
23489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
23499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
23509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
23519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w - (hw_w * v);
23529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = 1.0f;
23539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
23549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
23559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[0] = x;         vtx[1] = y;
23569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
23579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
23589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
23599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
23609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
23619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2362ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    VSyncWaiter vsync(mEventThread);
2363ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
2364a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian    // the full animation is 12 frames
2365a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian    int nbFrames = 8;
23669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itr(nbFrames, 7.5f);
23679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itg(nbFrames, 8.0f);
23689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itb(nbFrames, 8.5f);
23699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
23709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    h_stretch hverts(hw_w, hw_h);
23719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_BLEND);
23729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_TEXTURE_2D);
23739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
23749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=nbFrames-1 ; i>=0 ; i--) {
23759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float v = itg(i);
23769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hverts(vtx, v);
2377ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
2378ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        // wait for vsync
2379ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        vsync.wait();
2380ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
23819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
23829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColor4f(1-v, 1-v, 1-v, 1);
23839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
23849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
23859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
23869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2387a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian    nbFrames = 4;
23889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    v_stretch vverts(hw_w, hw_h);
23899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnable(GL_BLEND);
23909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBlendFunc(GL_ONE, GL_ONE);
23919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=nbFrames-1 ; i>=0 ; i--) {
23929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float x, y, w, h;
23939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vr = itr(i);
23949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vg = itg(i);
23959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vb = itb(i);
239659119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2397ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        // wait for vsync
2398ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        vsync.wait();
2399ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
24009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // clear screen
240159119e658a12279e8fff508f8773843de2d90917Mathias Agopian        glColorMask(1,1,1,1);
24029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
24039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glEnable(GL_TEXTURE_2D);
24049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
24059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the red plane
24069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vr);
24079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(1,0,0,1);
24089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
24099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
24109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the green plane
24119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vg);
24129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,1,0,1);
24139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
24149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
24159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the blue plane
24169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vb);
24179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,0,1,1);
24189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
24199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
24209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
242159119e658a12279e8fff508f8773843de2d90917Mathias Agopian    }
242259119e658a12279e8fff508f8773843de2d90917Mathias Agopian
24239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
24249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
242559119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glDeleteTextures(1, &tname);
2426a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    glDisable(GL_TEXTURE_2D);
2427c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_BLEND);
242859119e658a12279e8fff508f8773843de2d90917Mathias Agopian
24299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
24309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
24319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
24329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// ---------------------------------------------------------------------------
24339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2434abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOffImplLocked(int32_t mode)
24359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
243622ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian    ATRACE_CALL();
243722ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian
24381b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    DisplayHardware& hw(const_cast<DisplayHardware&>(getDefaultDisplayHardware()));
24399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (!hw.canDraw()) {
24409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // we're already off
24419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return NO_ERROR;
24429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
24437ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian
24447ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian    // turn off hwc while we're doing the animation
24458630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    getHwComposer().disable();
24467ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian    // and make sure to turn it back on (if needed) next time we compose
24477ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian    invalidateHwcGeometry();
24487ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian
2449abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    if (mode & ISurfaceComposer::eElectronBeamAnimationOff) {
2450abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        electronBeamOffAnimationImplLocked();
2451abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    }
2452abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian
2453abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    // always clear the whole screen at the end of the animation
2454abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    glClearColor(0,0,0,1);
2455abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    glClear(GL_COLOR_BUFFER_BIT);
2456abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    hw.flip( Region(hw.bounds()) );
2457abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian
2458015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian    return NO_ERROR;
245959119e658a12279e8fff508f8773843de2d90917Mathias Agopian}
246059119e658a12279e8fff508f8773843de2d90917Mathias Agopian
246159119e658a12279e8fff508f8773843de2d90917Mathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOff(int32_t mode)
246259119e658a12279e8fff508f8773843de2d90917Mathias Agopian{
246359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    class MessageTurnElectronBeamOff : public MessageBase {
246459119e658a12279e8fff508f8773843de2d90917Mathias Agopian        SurfaceFlinger* flinger;
2465abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        int32_t mode;
246659119e658a12279e8fff508f8773843de2d90917Mathias Agopian        status_t result;
246759119e658a12279e8fff508f8773843de2d90917Mathias Agopian    public:
2468abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        MessageTurnElectronBeamOff(SurfaceFlinger* flinger, int32_t mode)
2469abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            : flinger(flinger), mode(mode), result(PERMISSION_DENIED) {
247059119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
247159119e658a12279e8fff508f8773843de2d90917Mathias Agopian        status_t getResult() const {
247259119e658a12279e8fff508f8773843de2d90917Mathias Agopian            return result;
247359119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
247459119e658a12279e8fff508f8773843de2d90917Mathias Agopian        virtual bool handler() {
247559119e658a12279e8fff508f8773843de2d90917Mathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
2476abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            result = flinger->turnElectronBeamOffImplLocked(mode);
247759119e658a12279e8fff508f8773843de2d90917Mathias Agopian            return true;
247859119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
247959119e658a12279e8fff508f8773843de2d90917Mathias Agopian    };
248059119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2481abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    sp<MessageBase> msg = new MessageTurnElectronBeamOff(this, mode);
248259119e658a12279e8fff508f8773843de2d90917Mathias Agopian    status_t res = postMessageSync(msg);
248359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (res == NO_ERROR) {
248459119e658a12279e8fff508f8773843de2d90917Mathias Agopian        res = static_cast<MessageTurnElectronBeamOff*>( msg.get() )->getResult();
24859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
24869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // work-around: when the power-manager calls us we activate the
24879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // animation. eventually, the "on" animation will be called
24889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // by the power-manager itself
2489abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        mElectronBeamAnimationMode = mode;
249059119e658a12279e8fff508f8773843de2d90917Mathias Agopian    }
249159119e658a12279e8fff508f8773843de2d90917Mathias Agopian    return res;
249259119e658a12279e8fff508f8773843de2d90917Mathias Agopian}
249359119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2494edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
2495edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2496abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOnImplLocked(int32_t mode)
24979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
24981b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    DisplayHardware& hw(const_cast<DisplayHardware&>(getDefaultDisplayHardware()));
24999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (hw.canDraw()) {
25009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // we're already on
25019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return NO_ERROR;
25029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
2503abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    if (mode & ISurfaceComposer::eElectronBeamAnimationOn) {
2504abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        electronBeamOnAnimationImplLocked();
2505abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    }
2506a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian
2507a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian    // make sure to redraw the whole screen when the animation is done
2508a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian    mDirtyRegion.set(hw.bounds());
250999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    signalTransaction();
2510a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian
2511015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian    return NO_ERROR;
25129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
25139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
25149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOn(int32_t mode)
25159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
25169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class MessageTurnElectronBeamOn : public MessageBase {
25179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        SurfaceFlinger* flinger;
2518abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        int32_t mode;
25199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        status_t result;
25209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
2521abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        MessageTurnElectronBeamOn(SurfaceFlinger* flinger, int32_t mode)
2522abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            : flinger(flinger), mode(mode), result(PERMISSION_DENIED) {
25239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
25249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        status_t getResult() const {
25259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return result;
25269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
25279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        virtual bool handler() {
25289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
2529abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            result = flinger->turnElectronBeamOnImplLocked(mode);
25309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return true;
25319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
25329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
25339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2534abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    postMessageAsync( new MessageTurnElectronBeamOn(this, mode) );
25359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
25369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
25379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
25389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// ---------------------------------------------------------------------------
25399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
254074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopianstatus_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy,
254174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        sp<IMemoryHeap>* heap,
254274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t* w, uint32_t* h, PixelFormat* f,
2543bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t sw, uint32_t sh,
2544bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ, uint32_t maxLayerZ)
254574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{
2546fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian    ATRACE_CALL();
2547fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian
254874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    status_t result = PERMISSION_DENIED;
254974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
255074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // only one display supported for now
25513b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    if (CC_UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) {
255274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return BAD_VALUE;
25533b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
255474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
25553b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject()) {
255674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return INVALID_OPERATION;
25573b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
255874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
255974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // get screen geometry
25601b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    const DisplayHardware& hw(getDisplayHardware(dpy));
256174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const uint32_t hw_w = hw.getWidth();
256274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const uint32_t hw_h = hw.getHeight();
256374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
25643b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    // if we have secure windows on this display, never allow the screen capture
25653b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    if (hw.getSecureLayerVisible()) {
25663b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        return PERMISSION_DENIED;
25673b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
25683b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
25693b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    if ((sw > hw_w) || (sh > hw_h)) {
257074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return BAD_VALUE;
25713b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
257274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
257374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    sw = (!sw) ? hw_w : sw;
257474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    sh = (!sh) ? hw_h : sh;
257574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const size_t size = sw * sh * 4;
257674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
25779d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block    //ALOGD("screenshot: sw=%d, sh=%d, minZ=%d, maxZ=%d",
25781c71a47a6db679a3212f0c99e14f330d6da500faMathias Agopian    //        sw, sh, minLayerZ, maxLayerZ);
2579c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
258074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // make sure to clear all GL error flags
258174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    while ( glGetError() != GL_NO_ERROR ) ;
258274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
258374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // create a FBO
258474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    GLuint name, tname;
258574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glGenRenderbuffersOES(1, &tname);
258674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindRenderbufferOES(GL_RENDERBUFFER_OES, tname);
258774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA8_OES, sw, sh);
2588fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian
258974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glGenFramebuffersOES(1, &name);
259074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
259174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES,
259274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, tname);
259374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
259474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
2595c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
259674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    if (status == GL_FRAMEBUFFER_COMPLETE_OES) {
259774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
259874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // invert everything, b/c glReadPixel() below will invert the FB
259974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glViewport(0, 0, sw, sh);
260074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_PROJECTION);
260174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glPushMatrix();
260274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glLoadIdentity();
2603ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian        glOrthof(0, hw_w, hw_h, 0, 0, 1);
260474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_MODELVIEW);
260574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
260674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // redraw the screen entirely...
260774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glClearColor(0,0,0,1);
260874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
2609f653b897a449e10d6cbfb6e0812f7b0bb02d6482Mathias Agopian
26109575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        const LayerVector& layers(mDrawingState.layersSortedByZ);
26119575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        const size_t count = layers.size();
261274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        for (size_t i=0 ; i<count ; ++i) {
261374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            const sp<LayerBase>& layer(layers[i]);
2614b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian            const uint32_t flags = layer->drawingState().flags;
2615b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian            if (!(flags & ISurfaceComposer::eLayerHidden)) {
2616b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                const uint32_t z = layer->drawingState().z;
2617b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                if (z >= minLayerZ && z <= maxLayerZ) {
26181b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian                    layer->drawForSreenShot(hw);
2619b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                }
2620bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian            }
262174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        }
262274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
262374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // check for errors and return screen capture
262474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        if (glGetError() != GL_NO_ERROR) {
262574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // error while rendering
262674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            result = INVALID_OPERATION;
262774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        } else {
262874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // allocate shared memory large enough to hold the
262974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // screen capture
263074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            sp<MemoryHeapBase> base(
263174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    new MemoryHeapBase(size, 0, "screen-capture") );
263274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            void* const ptr = base->getBase();
263374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            if (ptr) {
263474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                // capture the screen with glReadPixels()
2635fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian                ScopedTrace _t(ATRACE_TAG, "glReadPixels");
263674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                glReadPixels(0, 0, sw, sh, GL_RGBA, GL_UNSIGNED_BYTE, ptr);
263774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                if (glGetError() == GL_NO_ERROR) {
263874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *heap = base;
263974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *w = sw;
264074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *h = sh;
264174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *f = PIXEL_FORMAT_RGBA_8888;
264274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    result = NO_ERROR;
264374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                }
264474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            } else {
264574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                result = NO_MEMORY;
264674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            }
264774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        }
264874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glViewport(0, 0, hw_w, hw_h);
264974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_PROJECTION);
265074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glPopMatrix();
265174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_MODELVIEW);
265274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    } else {
265374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        result = BAD_VALUE;
265474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    }
265574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
265674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // release FBO resources
265774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
265874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glDeleteRenderbuffersOES(1, &tname);
265974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glDeleteFramebuffersOES(1, &name);
2660e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian
2661e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian    hw.compositionComplete();
2662e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian
26639d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block    // ALOGD("screenshot: result = %s", result<0 ? strerror(result) : "OK");
2664c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
266574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    return result;
266674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian}
266774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
266874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
26691b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopianstatus_t SurfaceFlinger::captureScreen(DisplayID dpy,
26701b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        sp<IMemoryHeap>* heap,
267174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t* width, uint32_t* height, PixelFormat* format,
2672bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t sw, uint32_t sh,
2673bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ, uint32_t maxLayerZ)
26741b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian{
26751b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    // only one display supported for now
267699ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten    if (CC_UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
26771b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        return BAD_VALUE;
26781b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
26791b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
26801b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        return INVALID_OPERATION;
26811b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
26821b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    class MessageCaptureScreen : public MessageBase {
26831b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        SurfaceFlinger* flinger;
26841b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        DisplayID dpy;
26851b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        sp<IMemoryHeap>* heap;
26861b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        uint32_t* w;
26871b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        uint32_t* h;
26881b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        PixelFormat* f;
268974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t sw;
269074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t sh;
2691bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ;
2692bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t maxLayerZ;
26931b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        status_t result;
26941b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    public:
26951b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        MessageCaptureScreen(SurfaceFlinger* flinger, DisplayID dpy,
269674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                sp<IMemoryHeap>* heap, uint32_t* w, uint32_t* h, PixelFormat* f,
2697bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                uint32_t sw, uint32_t sh,
2698bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                uint32_t minLayerZ, uint32_t maxLayerZ)
26991b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            : flinger(flinger), dpy(dpy),
2700bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              heap(heap), w(w), h(h), f(f), sw(sw), sh(sh),
2701bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              minLayerZ(minLayerZ), maxLayerZ(maxLayerZ),
2702bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              result(PERMISSION_DENIED)
27031b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
27041b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
27051b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        status_t getResult() const {
27061b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            return result;
27071b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
27081b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        virtual bool handler() {
27091b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
271074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            result = flinger->captureScreenImplLocked(dpy,
2711bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                    heap, w, h, f, sw, sh, minLayerZ, maxLayerZ);
27121b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            return true;
27131b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
27141b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    };
27151b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
27161b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    sp<MessageBase> msg = new MessageCaptureScreen(this,
2717bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian            dpy, heap, width, height, format, sw, sh, minLayerZ, maxLayerZ);
27181b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    status_t res = postMessageSync(msg);
27191b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    if (res == NO_ERROR) {
27201b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        res = static_cast<MessageCaptureScreen*>( msg.get() )->getResult();
27211b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    }
27221b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    return res;
27231b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian}
27241b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
27251b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// ---------------------------------------------------------------------------
27261b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
2727921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::LayerVector::LayerVector() {
2728921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
2729921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
2730921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::LayerVector::LayerVector(const LayerVector& rhs)
2731921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    : SortedVector<sp<LayerBase> >(rhs) {
2732921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
2733921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
2734921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianint SurfaceFlinger::LayerVector::do_compare(const void* lhs,
2735921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    const void* rhs) const
2736edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2737921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    const sp<LayerBase>& l(*reinterpret_cast<const sp<LayerBase>*>(lhs));
2738921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    const sp<LayerBase>& r(*reinterpret_cast<const sp<LayerBase>*>(rhs));
2739921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    // sort layers by Z order
2740921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    uint32_t lz = l->currentState().z;
2741921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    uint32_t rz = r->currentState().z;
2742921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    // then by sequence, so we get a stable ordering
2743921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    return (lz != rz) ? (lz - rz) : (l->sequence - r->sequence);
2744921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
2745921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
2746921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian// ---------------------------------------------------------------------------
2747921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
2748921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::State::State()
2749921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    : orientation(ISurfaceComposer::eOrientationDefault),
2750921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian      orientationFlags(0) {
2751b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
27527303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
2753b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// ---------------------------------------------------------------------------
275496f0819f81293076e652792794a961543e6750d7Mathias Agopian
27559a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::GraphicBufferAlloc() {}
27569a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
27579a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::~GraphicBufferAlloc() {}
27589a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
27599a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h,
2760d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        PixelFormat format, uint32_t usage, status_t* error) {
27619a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(w, h, format, usage));
27629a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    status_t err = graphicBuffer->initCheck();
2763d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian    *error = err;
2764a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (err != 0 || graphicBuffer->handle == 0) {
2765d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        if (err == NO_MEMORY) {
2766d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian            GraphicBuffer::dumpAllocationsToSystemLog();
2767d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        }
2768e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE("GraphicBufferAlloc::createGraphicBuffer(w=%d, h=%d) "
2769a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian             "failed (%s), handle=%p",
2770a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                w, h, strerror(-err), graphicBuffer->handle);
27719a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis        return 0;
27729a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    }
27739a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    return graphicBuffer;
27749a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis}
27759a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
27769a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis// ---------------------------------------------------------------------------
27779a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
2778edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
2779